sorbet-runtime 0.5.5316 → 0.5.5325
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/sorbet-runtime.rb +2 -1
- data/lib/types/private/types/void.rb +4 -3
- data/lib/types/props/constructor.rb +24 -10
- data/lib/types/props/optional.rb +29 -13
- data/lib/types/props/private/apply_default.rb +170 -0
- data/lib/types/props/weak_constructor.rb +47 -15
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e0334f17e13c054564e58b5baae0c6d7af794f0f9bb2a6c009b8c66a3ca6c2c
|
4
|
+
data.tar.gz: 3dfd7376f2c8259102b83724f2536a9094724a8d3ec15f89e86c24dcd56655f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91ccdef7e77ca422b938d018b7c06f5f6d67da79589a1c06e5bfb87c65cd94f198512ad537e086b7810b4be3b51b0d264d236afc07d14034dd800dccf754f508
|
7
|
+
data.tar.gz: 14e060cef09fd1b3c2937b879e31a27755182e40d65803aa8a2d98db51ac73617d08ca92f1f4fd321a2d7fbf988b515414b8967ca805d9be09f8d98f33c870d5
|
data/lib/sorbet-runtime.rb
CHANGED
@@ -92,8 +92,10 @@ require_relative 'types/props/decorator'
|
|
92
92
|
require_relative 'types/props/errors'
|
93
93
|
require_relative 'types/props/plugin'
|
94
94
|
require_relative 'types/props/utils'
|
95
|
+
require_relative 'types/enum'
|
95
96
|
# Props that run sigs statically so have to be after all the others :(
|
96
97
|
require_relative 'types/props/private/setter_factory'
|
98
|
+
require_relative 'types/props/private/apply_default'
|
97
99
|
require_relative 'types/props/optional'
|
98
100
|
require_relative 'types/props/weak_constructor'
|
99
101
|
require_relative 'types/props/constructor'
|
@@ -102,6 +104,5 @@ require_relative 'types/props/serializable'
|
|
102
104
|
require_relative 'types/props/type_validation'
|
103
105
|
|
104
106
|
require_relative 'types/struct'
|
105
|
-
require_relative 'types/enum'
|
106
107
|
|
107
108
|
require_relative 'types/compatibility_patches'
|
@@ -8,13 +8,14 @@ class T::Private::Types::Void < T::Types::Base
|
|
8
8
|
|
9
9
|
# The actual return value of `.void` methods.
|
10
10
|
#
|
11
|
-
# Uses `
|
12
|
-
# of the constant it's assigned to. This gives it a readable name someone
|
11
|
+
# Uses `module VOID` because this gives it a readable name when someone
|
13
12
|
# examines it in Pry or with `#inspect` like:
|
14
13
|
#
|
15
14
|
# T::Private::Types::Void::VOID
|
16
15
|
#
|
17
|
-
VOID
|
16
|
+
module VOID
|
17
|
+
freeze
|
18
|
+
end
|
18
19
|
|
19
20
|
# @override Base
|
20
21
|
def name
|
@@ -3,18 +3,32 @@
|
|
3
3
|
|
4
4
|
module T::Props::Constructor
|
5
5
|
include T::Props::WeakConstructor
|
6
|
+
end
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
module T::Props::Constructor::DecoratorMethods
|
9
|
+
extend T::Sig
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
# Set values for all props that have no defaults. Override what `WeakConstructor`
|
12
|
+
# does in order to raise errors on nils instead of ignoring them.
|
13
|
+
#
|
14
|
+
# @return [Integer] A count of props that we successfully initialized (which
|
15
|
+
# we'll use to check for any unrecognized input.)
|
16
|
+
#
|
17
|
+
# checked(:never) - O(runtime object construction)
|
18
|
+
sig {params(instance: T::Props::Constructor, hash: T::Hash[Symbol, T.untyped]).returns(Integer).checked(:never)}
|
19
|
+
def construct_props_without_defaults(instance, hash)
|
20
|
+
@props_without_defaults&.count do |p, setter_proc|
|
21
|
+
begin
|
22
|
+
val = hash[p]
|
23
|
+
instance.instance_exec(val, &setter_proc)
|
24
|
+
val || hash.key?(p)
|
25
|
+
rescue TypeError, T::Props::InvalidValueError
|
26
|
+
if !hash.key?(p)
|
27
|
+
raise ArgumentError.new("Missing required prop `#{p}` for class `#{instance.class.name}`")
|
28
|
+
else
|
29
|
+
raise
|
30
|
+
end
|
15
31
|
end
|
16
|
-
end
|
17
|
-
|
18
|
-
super
|
32
|
+
end || 0
|
19
33
|
end
|
20
34
|
end
|
data/lib/types/props/optional.rb
CHANGED
@@ -12,6 +12,8 @@ end
|
|
12
12
|
# NB: This must stay in the same file where T::Props::Optional is defined due to
|
13
13
|
# T::Props::Decorator#apply_plugin; see https://git.corp.stripe.com/stripe-internal/pay-server/blob/fc7f15593b49875f2d0499ffecfd19798bac05b3/chalk/odm/lib/chalk-odm/document_decorator.rb#L716-L717
|
14
14
|
module T::Props::Optional::DecoratorMethods
|
15
|
+
extend T::Sig
|
16
|
+
|
15
17
|
# TODO: clean this up. This set of options is confusing, and some of them are not universally
|
16
18
|
# applicable (e.g., :on_load only applies when using T::Serializable).
|
17
19
|
VALID_OPTIONAL_RULES = Set[
|
@@ -28,6 +30,9 @@ module T::Props::Optional::DecoratorMethods
|
|
28
30
|
}.freeze
|
29
31
|
private_constant :VALID_RULE_KEYS
|
30
32
|
|
33
|
+
DEFAULT_SETTER_RULE_KEY = :_t_props_private_apply_default
|
34
|
+
private_constant :DEFAULT_SETTER_RULE_KEY
|
35
|
+
|
31
36
|
def valid_rule_key?(key)
|
32
37
|
super || VALID_RULE_KEYS[key]
|
33
38
|
end
|
@@ -39,8 +44,30 @@ module T::Props::Optional::DecoratorMethods
|
|
39
44
|
rules[:need_nil_read_check] = T::Props::Utils.need_nil_read_check?(rules)
|
40
45
|
end
|
41
46
|
|
47
|
+
# checked(:never) - O(runtime object construction)
|
48
|
+
sig {returns(T::Hash[Symbol, T::Props::Private::ApplyDefault]).checked(:never)}
|
49
|
+
attr_reader :props_with_defaults
|
50
|
+
|
51
|
+
# checked(:never) - O(runtime object construction)
|
52
|
+
sig {returns(T::Hash[Symbol, T::Props::Private::SetterFactory::SetterProc]).checked(:never)}
|
53
|
+
attr_reader :props_without_defaults
|
54
|
+
|
42
55
|
def add_prop_definition(prop, rules)
|
43
56
|
compute_derived_rules(rules)
|
57
|
+
|
58
|
+
default_setter = T::Props::Private::ApplyDefault.for(decorated_class, rules)
|
59
|
+
if default_setter
|
60
|
+
@props_with_defaults ||= {}
|
61
|
+
@props_with_defaults[prop] = default_setter
|
62
|
+
@props_without_defaults&.delete(prop) # Handle potential override
|
63
|
+
|
64
|
+
rules[DEFAULT_SETTER_RULE_KEY] = default_setter
|
65
|
+
else
|
66
|
+
@props_without_defaults ||= {}
|
67
|
+
@props_without_defaults[prop] = rules.fetch(:setter_proc)
|
68
|
+
@props_with_defaults&.delete(prop) # Handle potential override
|
69
|
+
end
|
70
|
+
|
44
71
|
super
|
45
72
|
end
|
46
73
|
|
@@ -61,21 +88,10 @@ module T::Props::Optional::DecoratorMethods
|
|
61
88
|
end
|
62
89
|
|
63
90
|
def has_default?(rules)
|
64
|
-
rules.include?(
|
91
|
+
rules.include?(DEFAULT_SETTER_RULE_KEY)
|
65
92
|
end
|
66
93
|
|
67
94
|
def get_default(rules, instance_class)
|
68
|
-
|
69
|
-
default = rules[:default]
|
70
|
-
T::Props::Utils.deep_clone_object(default)
|
71
|
-
elsif rules.include?(:factory)
|
72
|
-
# Factory should never be nil if the key is specified, but
|
73
|
-
# we do this rather than 'elsif rules[:factory]' for
|
74
|
-
# consistency with :default.
|
75
|
-
factory = rules[:factory]
|
76
|
-
instance_class.class_exec(&factory)
|
77
|
-
else
|
78
|
-
nil
|
79
|
-
end
|
95
|
+
rules[DEFAULT_SETTER_RULE_KEY]&.default
|
80
96
|
end
|
81
97
|
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module T::Props
|
5
|
+
module Private
|
6
|
+
class ApplyDefault
|
7
|
+
extend T::Sig
|
8
|
+
extend T::Helpers
|
9
|
+
abstract!
|
10
|
+
|
11
|
+
# checked(:never) - O(object construction x prop count)
|
12
|
+
sig {returns(SetterFactory::SetterProc).checked(:never)}
|
13
|
+
attr_reader :setter_proc
|
14
|
+
|
15
|
+
# checked(:never) - We do this with `T.let` instead
|
16
|
+
sig {params(accessor_key: Symbol, setter_proc: SetterFactory::SetterProc).void.checked(:never)}
|
17
|
+
def initialize(accessor_key, setter_proc)
|
18
|
+
@accessor_key = T.let(accessor_key, Symbol)
|
19
|
+
@setter_proc = T.let(setter_proc, SetterFactory::SetterProc)
|
20
|
+
end
|
21
|
+
|
22
|
+
# checked(:never) - O(object construction x prop count)
|
23
|
+
sig {abstract.returns(T.untyped).checked(:never)}
|
24
|
+
def default; end
|
25
|
+
|
26
|
+
# checked(:never) - O(object construction x prop count)
|
27
|
+
sig {abstract.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)}
|
28
|
+
def set_default(instance); end
|
29
|
+
|
30
|
+
NO_CLONE_TYPES = T.let([TrueClass, FalseClass, NilClass, Symbol, Numeric, T::Enum].freeze, T::Array[Module])
|
31
|
+
|
32
|
+
# checked(:never) - Rules hash is expensive to check
|
33
|
+
sig {params(cls: Module, rules: T::Hash[Symbol, T.untyped]).returns(T.nilable(ApplyDefault)).checked(:never)}
|
34
|
+
def self.for(cls, rules)
|
35
|
+
accessor_key = rules.fetch(:accessor_key)
|
36
|
+
setter = rules.fetch(:setter_proc)
|
37
|
+
|
38
|
+
if rules.key?(:factory)
|
39
|
+
ApplyDefaultFactory.new(cls, rules.fetch(:factory), accessor_key, setter)
|
40
|
+
elsif rules.key?(:default)
|
41
|
+
default = rules.fetch(:default)
|
42
|
+
case default
|
43
|
+
when *NO_CLONE_TYPES
|
44
|
+
return ApplyPrimitiveDefault.new(default, accessor_key, setter)
|
45
|
+
when String
|
46
|
+
if default.frozen?
|
47
|
+
return ApplyPrimitiveDefault.new(default, accessor_key, setter)
|
48
|
+
end
|
49
|
+
when Array
|
50
|
+
if default.empty? && default.class == Array
|
51
|
+
return ApplyEmptyArrayDefault.new(accessor_key, setter)
|
52
|
+
end
|
53
|
+
when Hash
|
54
|
+
if default.empty? && default.default.nil? && T.unsafe(default).default_proc.nil? && default.class == Hash
|
55
|
+
return ApplyEmptyHashDefault.new(accessor_key, setter)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
ApplyComplexDefault.new(default, accessor_key, setter)
|
60
|
+
else
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class ApplyFixedDefault < ApplyDefault
|
67
|
+
abstract!
|
68
|
+
|
69
|
+
# checked(:never) - We do this with `T.let` instead
|
70
|
+
sig {params(default: BasicObject, accessor_key: Symbol, setter_proc: SetterFactory::SetterProc).void.checked(:never)}
|
71
|
+
def initialize(default, accessor_key, setter_proc)
|
72
|
+
# FIXME: Ideally we'd check here that the default is actually a valid
|
73
|
+
# value for this field, but existing code relies on the fact that we don't.
|
74
|
+
#
|
75
|
+
# :(
|
76
|
+
#
|
77
|
+
# setter_proc.call(default)
|
78
|
+
@default = T.let(default, BasicObject)
|
79
|
+
super(accessor_key, setter_proc)
|
80
|
+
end
|
81
|
+
|
82
|
+
# checked(:never) - O(object construction x prop count)
|
83
|
+
sig {override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)}
|
84
|
+
def set_default(instance)
|
85
|
+
instance.instance_variable_set(@accessor_key, default)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
class ApplyPrimitiveDefault < ApplyFixedDefault
|
90
|
+
# checked(:never) - O(object construction x prop count)
|
91
|
+
sig {override.returns(T.untyped).checked(:never)}
|
92
|
+
attr_reader :default
|
93
|
+
end
|
94
|
+
|
95
|
+
class ApplyComplexDefault < ApplyFixedDefault
|
96
|
+
# checked(:never) - O(object construction x prop count)
|
97
|
+
sig {override.returns(T.untyped).checked(:never)}
|
98
|
+
def default
|
99
|
+
T::Props::Utils.deep_clone_object(@default)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Special case since it's so common, and a literal `[]` is meaningfully
|
104
|
+
# faster than falling back to ApplyComplexDefault or even calling
|
105
|
+
# `some_empty_array.dup`
|
106
|
+
class ApplyEmptyArrayDefault < ApplyDefault
|
107
|
+
# checked(:never) - O(object construction x prop count)
|
108
|
+
sig {override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)}
|
109
|
+
def set_default(instance)
|
110
|
+
instance.instance_variable_set(@accessor_key, [])
|
111
|
+
end
|
112
|
+
|
113
|
+
# checked(:never) - O(object construction x prop count)
|
114
|
+
sig {override.returns(T::Array[T.untyped]).checked(:never)}
|
115
|
+
def default
|
116
|
+
[]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Special case since it's so common, and a literal `{}` is meaningfully
|
121
|
+
# faster than falling back to ApplyComplexDefault or even calling
|
122
|
+
# `some_empty_hash.dup`
|
123
|
+
class ApplyEmptyHashDefault < ApplyDefault
|
124
|
+
# checked(:never) - O(object construction x prop count)
|
125
|
+
sig {override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)}
|
126
|
+
def set_default(instance)
|
127
|
+
instance.instance_variable_set(@accessor_key, {})
|
128
|
+
end
|
129
|
+
|
130
|
+
# checked(:never) - O(object construction x prop count)
|
131
|
+
sig {override.returns(T::Hash[T.untyped, T.untyped]).checked(:never)}
|
132
|
+
def default
|
133
|
+
{}
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
class ApplyDefaultFactory < ApplyDefault
|
138
|
+
# checked(:never) - We do this with `T.let` instead
|
139
|
+
sig do
|
140
|
+
params(
|
141
|
+
cls: Module,
|
142
|
+
factory: T.any(Proc, Method),
|
143
|
+
accessor_key: Symbol,
|
144
|
+
setter_proc: SetterFactory::SetterProc,
|
145
|
+
)
|
146
|
+
.void
|
147
|
+
.checked(:never)
|
148
|
+
end
|
149
|
+
def initialize(cls, factory, accessor_key, setter_proc)
|
150
|
+
@class = T.let(cls, Module)
|
151
|
+
@factory = T.let(factory, T.any(Proc, Method))
|
152
|
+
super(accessor_key, setter_proc)
|
153
|
+
end
|
154
|
+
|
155
|
+
# checked(:never) - O(object construction x prop count)
|
156
|
+
sig {override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)}
|
157
|
+
def set_default(instance)
|
158
|
+
# Use the actual setter to validate the factory returns a legitimate
|
159
|
+
# value every time
|
160
|
+
instance.instance_exec(default, &@setter_proc)
|
161
|
+
end
|
162
|
+
|
163
|
+
# checked(:never) - O(object construction x prop count)
|
164
|
+
sig {override.returns(T.untyped).checked(:never)}
|
165
|
+
def default
|
166
|
+
@class.class_exec(&@factory)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
@@ -3,28 +3,60 @@
|
|
3
3
|
|
4
4
|
module T::Props::WeakConstructor
|
5
5
|
include T::Props::Optional
|
6
|
+
extend T::Sig
|
6
7
|
|
8
|
+
# checked(:never) - O(runtime object construction)
|
9
|
+
sig {params(hash: T::Hash[Symbol, T.untyped]).void.checked(:never)}
|
7
10
|
def initialize(hash={})
|
8
|
-
expected_keys = {}
|
9
|
-
hash.each_key {|key| expected_keys[key] = true}
|
10
|
-
|
11
11
|
decorator = self.class.decorator
|
12
12
|
|
13
|
-
decorator.
|
13
|
+
hash_keys_matching_props = decorator.construct_props_with_defaults(self, hash) +
|
14
|
+
decorator.construct_props_without_defaults(self, hash)
|
15
|
+
|
16
|
+
if hash_keys_matching_props < hash.size
|
17
|
+
raise ArgumentError.new("#{self.class}: Unrecognized properties: #{(hash.keys - decorator.props.keys).join(', ')}")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module T::Props::WeakConstructor::DecoratorMethods
|
23
|
+
extend T::Sig
|
24
|
+
|
25
|
+
# Set values for all props that have no defaults. Ignore any not present.
|
26
|
+
#
|
27
|
+
# @return [Integer] A count of props that we successfully initialized (which
|
28
|
+
# we'll use to check for any unrecognized input.)
|
29
|
+
#
|
30
|
+
# checked(:never) - O(runtime object construction)
|
31
|
+
sig {params(instance: T::Props::WeakConstructor, hash: T::Hash[Symbol, T.untyped]).returns(Integer).checked(:never)}
|
32
|
+
def construct_props_without_defaults(instance, hash)
|
33
|
+
@props_without_defaults&.count do |p, setter_proc|
|
14
34
|
if hash.key?(p)
|
15
|
-
|
16
|
-
|
17
|
-
elsif decorator.has_default?(rules)
|
18
|
-
val = decorator.get_default(rules, self.class)
|
35
|
+
instance.instance_exec(hash[p], &setter_proc)
|
36
|
+
true
|
19
37
|
else
|
20
|
-
|
38
|
+
false
|
21
39
|
end
|
40
|
+
end || 0
|
41
|
+
end
|
22
42
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
43
|
+
# Set values for all props that have defaults. Use the default if and only if
|
44
|
+
# the prop key isn't in the input.
|
45
|
+
#
|
46
|
+
# @return [Integer] A count of props that we successfully initialized (which
|
47
|
+
# we'll use to check for any unrecognized input.)
|
48
|
+
#
|
49
|
+
# checked(:never) - O(runtime object construction)
|
50
|
+
sig {params(instance: T::Props::WeakConstructor, hash: T::Hash[Symbol, T.untyped]).returns(Integer).checked(:never)}
|
51
|
+
def construct_props_with_defaults(instance, hash)
|
52
|
+
@props_with_defaults&.count do |p, default_struct|
|
53
|
+
if hash.key?(p)
|
54
|
+
instance.instance_exec(hash[p], &default_struct.setter_proc)
|
55
|
+
true
|
56
|
+
else
|
57
|
+
default_struct.set_default(instance)
|
58
|
+
false
|
59
|
+
end
|
60
|
+
end || 0
|
29
61
|
end
|
30
62
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sorbet-runtime
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.5325
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stripe
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-01
|
11
|
+
date: 2020-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -112,6 +112,7 @@ files:
|
|
112
112
|
- lib/types/props/optional.rb
|
113
113
|
- lib/types/props/plugin.rb
|
114
114
|
- lib/types/props/pretty_printable.rb
|
115
|
+
- lib/types/props/private/apply_default.rb
|
115
116
|
- lib/types/props/private/setter_factory.rb
|
116
117
|
- lib/types/props/serializable.rb
|
117
118
|
- lib/types/props/type_validation.rb
|