sorbet-runtime 0.5.5200 → 0.5.5226
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/types/_types.rb +1 -5
- data/lib/types/enum.rb +6 -6
- data/lib/types/props/_props.rb +2 -2
- data/lib/types/props/decorator.rb +103 -46
- data/lib/types/props/optional.rb +9 -6
- data/lib/types/props/pretty_printable.rb +3 -3
- data/lib/types/props/serializable.rb +6 -6
- data/lib/types/props/type_validation.rb +6 -4
- data/lib/types/utils.rb +4 -2
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ce5d31efe70f4a4a9fedee60cddc4545cce308285d1a92e9b75f7c6c5cfd0ead
|
|
4
|
+
data.tar.gz: 8ff1cb8a2b9a7c0f1987925899bfcf674c27b594156c9dd8e60ee27ec51d1dd1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bc94cf76fd49747ab049a66bfbd30dc4a0b037ac0f8988a4c6f6a5e6421abf92f209c14a8fe42c0268ca34d8fa5e77cc4fcddc24f08bd8cc6e7175068cc0285e
|
|
7
|
+
data.tar.gz: 38dc583fc54332f763cb1982bce24e5c23e2d2125a0dfd451354eb16f5adc8bab07ee2c4cfda1642b83795bc1539d153b7063df2ffd367faa4d1798ca856cd13
|
data/lib/types/_types.rb
CHANGED
|
@@ -65,12 +65,8 @@ module T
|
|
|
65
65
|
T::Types::SelfType.new
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
-
# TODO(jez) Matches the instance type in a singleton-class context
|
|
69
|
-
def self.attached_class
|
|
70
|
-
T::Types::AttachedClassType.new
|
|
71
|
-
end
|
|
72
68
|
# Matches the instance type in a singleton-class context
|
|
73
|
-
def self.
|
|
69
|
+
def self.attached_class
|
|
74
70
|
T::Types::AttachedClassType.new
|
|
75
71
|
end
|
|
76
72
|
|
data/lib/types/enum.rb
CHANGED
|
@@ -48,7 +48,7 @@ class T::Enum
|
|
|
48
48
|
private_constant :SerializedVal
|
|
49
49
|
|
|
50
50
|
## Enum class methods ##
|
|
51
|
-
sig {returns(T::Array[T.
|
|
51
|
+
sig {returns(T::Array[T.attached_class])}
|
|
52
52
|
def self.values
|
|
53
53
|
if @values.nil?
|
|
54
54
|
raise "Attempting to access values of #{self.class} before it has been initialized." \
|
|
@@ -61,7 +61,7 @@ class T::Enum
|
|
|
61
61
|
#
|
|
62
62
|
# Note: It would have been nice to make this method final before people started overriding it.
|
|
63
63
|
# Note: Failed CriticalMethodsNoRuntimeTypingTest
|
|
64
|
-
sig {params(serialized_val: SerializedVal).returns(T.nilable(T.
|
|
64
|
+
sig {params(serialized_val: SerializedVal).returns(T.nilable(T.attached_class)).checked(:never)}
|
|
65
65
|
def self.try_deserialize(serialized_val)
|
|
66
66
|
if @mapping.nil?
|
|
67
67
|
raise "Attempting to access serialization map of #{self.class} before it has been initialized." \
|
|
@@ -77,7 +77,7 @@ class T::Enum
|
|
|
77
77
|
#
|
|
78
78
|
# @return [self]
|
|
79
79
|
# @raise [KeyError] if serialized value does not match any instance.
|
|
80
|
-
sig {overridable.params(serialized_val: SerializedVal).returns(T.
|
|
80
|
+
sig {overridable.params(serialized_val: SerializedVal).returns(T.attached_class).checked(:never)}
|
|
81
81
|
def self.from_serialized(serialized_val)
|
|
82
82
|
res = try_deserialize(serialized_val)
|
|
83
83
|
if res.nil?
|
|
@@ -124,7 +124,7 @@ class T::Enum
|
|
|
124
124
|
end
|
|
125
125
|
|
|
126
126
|
# Note: Failed CriticalMethodsNoRuntimeTypingTest
|
|
127
|
-
sig {params(mongo_value: SerializedVal).returns(T.
|
|
127
|
+
sig {params(mongo_value: SerializedVal).returns(T.attached_class).checked(:never)}
|
|
128
128
|
def self.deserialize(mongo_value)
|
|
129
129
|
if self == T::Enum
|
|
130
130
|
raise "Cannot call T::Enum.deserialize directly. You must call on a specific child class."
|
|
@@ -310,8 +310,8 @@ class T::Enum
|
|
|
310
310
|
|
|
311
311
|
yield
|
|
312
312
|
|
|
313
|
-
@values = T.let(nil, T.nilable(T::Array[T.
|
|
314
|
-
@mapping = T.let(nil, T.nilable(T::Hash[SerializedVal, T.
|
|
313
|
+
@values = T.let(nil, T.nilable(T::Array[T.attached_class]))
|
|
314
|
+
@mapping = T.let(nil, T.nilable(T::Hash[SerializedVal, T.attached_class]))
|
|
315
315
|
|
|
316
316
|
# Freeze the Enum class and bind the constant names into each of the instances.
|
|
317
317
|
@mapping = {}
|
data/lib/types/props/_props.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
# typed:
|
|
2
|
+
# typed: true
|
|
3
3
|
|
|
4
4
|
# A mixin for defining typed properties (attributes).
|
|
5
5
|
# To get serialization methods (to/from JSON-style hashes), add T::Props::Serializable.
|
|
@@ -131,7 +131,7 @@ module T::Props
|
|
|
131
131
|
sig {params(name: T.any(Symbol, String), cls_or_args: T.untyped, args: T::Hash[Symbol, T.untyped]).void}
|
|
132
132
|
def const(name, cls_or_args, args={})
|
|
133
133
|
if (cls_or_args.is_a?(Hash) && cls_or_args.key?(:immutable)) || args.key?(:immutable)
|
|
134
|
-
raise ArgumentError.new("Cannot pass 'immutable' argument when using 'const' keyword to define a prop")
|
|
134
|
+
Kernel.raise ArgumentError.new("Cannot pass 'immutable' argument when using 'const' keyword to define a prop")
|
|
135
135
|
end
|
|
136
136
|
|
|
137
137
|
if cls_or_args.is_a?(Hash)
|
|
@@ -18,7 +18,7 @@ class T::Props::Decorator
|
|
|
18
18
|
|
|
19
19
|
class NoRulesError < StandardError; end
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
sig {params(klass: DecoratedClass).void.checked(:never)}
|
|
22
22
|
def initialize(klass)
|
|
23
23
|
@class = klass
|
|
24
24
|
klass.plugins.each do |mod|
|
|
@@ -26,7 +26,7 @@ class T::Props::Decorator
|
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
# prop
|
|
29
|
+
# checked(:never) - O(prop accesses)
|
|
30
30
|
sig {returns(T::Hash[Symbol, Rules]).checked(:never)}
|
|
31
31
|
def props
|
|
32
32
|
@props ||= {}.freeze
|
|
@@ -44,12 +44,13 @@ class T::Props::Decorator
|
|
|
44
44
|
sig {returns(T::Array[Symbol])}
|
|
45
45
|
def all_props; props.keys; end
|
|
46
46
|
|
|
47
|
+
# checked(:never) - O(prop accesses)
|
|
47
48
|
sig {params(prop: T.any(Symbol, String)).returns(Rules).checked(:never)}
|
|
48
49
|
def prop_rules(prop); props[prop.to_sym] || raise("No such prop: #{prop.inspect}"); end
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
# checked(:never) - Rules hash is expensive to check
|
|
52
|
+
sig {params(prop: Symbol, rules: Rules).void.checked(:never)}
|
|
51
53
|
def add_prop_definition(prop, rules)
|
|
52
|
-
prop = prop.to_sym
|
|
53
54
|
override = rules.delete(:override)
|
|
54
55
|
|
|
55
56
|
if props.include?(prop) && !override
|
|
@@ -61,25 +62,36 @@ class T::Props::Decorator
|
|
|
61
62
|
@props = @props.merge(prop => rules.freeze).freeze
|
|
62
63
|
end
|
|
63
64
|
|
|
64
|
-
|
|
65
|
+
VALID_RULE_KEYS = %i{
|
|
66
|
+
enum
|
|
67
|
+
foreign
|
|
68
|
+
foreign_hint_only
|
|
69
|
+
ifunset
|
|
70
|
+
immutable
|
|
71
|
+
override
|
|
72
|
+
redaction
|
|
73
|
+
sensitivity
|
|
74
|
+
without_accessors
|
|
75
|
+
clobber_existing_method!
|
|
76
|
+
extra
|
|
77
|
+
optional
|
|
78
|
+
_tnilable
|
|
79
|
+
}.to_set.freeze
|
|
80
|
+
private_constant :VALID_RULE_KEYS
|
|
81
|
+
|
|
82
|
+
sig {params(key: Symbol).returns(T::Boolean).checked(:never)}
|
|
83
|
+
def valid_rule_key?(key)
|
|
84
|
+
valid_props.include?(key)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Deprecated, kept temporarily to support overrides in pay-server
|
|
88
|
+
# during the transition to `valid_rule_key?`
|
|
89
|
+
sig {returns(T::Set[Symbol]).checked(:never)}
|
|
65
90
|
def valid_props
|
|
66
|
-
|
|
67
|
-
enum
|
|
68
|
-
foreign
|
|
69
|
-
foreign_hint_only
|
|
70
|
-
ifunset
|
|
71
|
-
immutable
|
|
72
|
-
override
|
|
73
|
-
redaction
|
|
74
|
-
sensitivity
|
|
75
|
-
without_accessors
|
|
76
|
-
clobber_existing_method!
|
|
77
|
-
extra
|
|
78
|
-
optional
|
|
79
|
-
_tnilable
|
|
80
|
-
}
|
|
91
|
+
VALID_RULE_KEYS
|
|
81
92
|
end
|
|
82
93
|
|
|
94
|
+
# checked(:never) - O(prop accesses)
|
|
83
95
|
sig {returns(DecoratedClass).checked(:never)}
|
|
84
96
|
def decorated_class; @class; end
|
|
85
97
|
|
|
@@ -87,6 +99,8 @@ class T::Props::Decorator
|
|
|
87
99
|
|
|
88
100
|
# For performance, don't use named params here.
|
|
89
101
|
# Passing in rules here is purely a performance optimization.
|
|
102
|
+
#
|
|
103
|
+
# checked(:never) - O(prop accesses)
|
|
90
104
|
sig do
|
|
91
105
|
params(
|
|
92
106
|
instance: DecoratedInstance,
|
|
@@ -104,6 +118,8 @@ class T::Props::Decorator
|
|
|
104
118
|
|
|
105
119
|
# For performance, don't use named params here.
|
|
106
120
|
# Passing in rules here is purely a performance optimization.
|
|
121
|
+
#
|
|
122
|
+
# checked(:never) - O(prop accesses)
|
|
107
123
|
sig do
|
|
108
124
|
params(
|
|
109
125
|
instance: DecoratedInstance,
|
|
@@ -121,6 +137,8 @@ class T::Props::Decorator
|
|
|
121
137
|
end
|
|
122
138
|
|
|
123
139
|
# Use this to validate that a value will validate for a given prop. Useful for knowing whether a value can be set on a model without setting it.
|
|
140
|
+
#
|
|
141
|
+
# checked(:never) - potentially O(prop accesses) depending on usage pattern
|
|
124
142
|
sig {params(prop: Symbol, val: T.untyped).void.checked(:never)}
|
|
125
143
|
def validate_prop_value(prop, val)
|
|
126
144
|
# This implements a 'public api' on document so that we don't allow callers to pass in rules
|
|
@@ -129,6 +147,8 @@ class T::Props::Decorator
|
|
|
129
147
|
end
|
|
130
148
|
|
|
131
149
|
# Passing in rules here is purely a performance optimization.
|
|
150
|
+
#
|
|
151
|
+
# checked(:never) - O(prop accesses)
|
|
132
152
|
sig {params(prop: Symbol, val: T.untyped, rules: Rules).void.checked(:never)}
|
|
133
153
|
private def check_prop_type(prop, val, rules=prop_rules(prop))
|
|
134
154
|
type_object = rules.fetch(:type_object)
|
|
@@ -184,6 +204,8 @@ class T::Props::Decorator
|
|
|
184
204
|
# Unlike the other methods that take rules, this one calls prop_rules for
|
|
185
205
|
# the default, which raises if the prop doesn't exist (this maintains
|
|
186
206
|
# preexisting behavior).
|
|
207
|
+
#
|
|
208
|
+
# checked(:never) - O(prop accesses)
|
|
187
209
|
sig do
|
|
188
210
|
params(
|
|
189
211
|
instance: DecoratedInstance,
|
|
@@ -201,6 +223,11 @@ class T::Props::Decorator
|
|
|
201
223
|
|
|
202
224
|
# For performance, don't use named params here.
|
|
203
225
|
# Passing in rules here is purely a performance optimization.
|
|
226
|
+
#
|
|
227
|
+
# Note this path is NOT used by generated getters on instances,
|
|
228
|
+
# unless `ifunset` is used on the prop, or `prop_get` is overridden.
|
|
229
|
+
#
|
|
230
|
+
# checked(:never) - O(prop accesses)
|
|
204
231
|
sig do
|
|
205
232
|
params(
|
|
206
233
|
instance: DecoratedInstance,
|
|
@@ -213,15 +240,7 @@ class T::Props::Decorator
|
|
|
213
240
|
def prop_get(instance, prop, rules=props[prop.to_sym])
|
|
214
241
|
val = get(instance, prop, rules)
|
|
215
242
|
|
|
216
|
-
|
|
217
|
-
# that `== nil` can return true while `.nil?` returns false. Tests will break in mysterious
|
|
218
|
-
# ways. A special thanks to Ruby for enabling this type of bug.
|
|
219
|
-
#
|
|
220
|
-
# One side effect here is that _if_ a class (like BSON::ByteBuffer) defines ==
|
|
221
|
-
# in such a way that instances which are not `nil`, ie are not NilClass, nevertheless
|
|
222
|
-
# are `== nil`, then we will transparently convert such instances to `nil` on read.
|
|
223
|
-
# Yes, our code relies on this behavior (as of writing). :thisisfine:
|
|
224
|
-
if val != nil # rubocop:disable Style/NonNilCheck
|
|
243
|
+
if !val.nil?
|
|
225
244
|
val
|
|
226
245
|
else
|
|
227
246
|
raise NoRulesError.new if !rules
|
|
@@ -234,6 +253,7 @@ class T::Props::Decorator
|
|
|
234
253
|
end
|
|
235
254
|
end
|
|
236
255
|
|
|
256
|
+
# checked(:never) - O(prop accesses)
|
|
237
257
|
sig do
|
|
238
258
|
params(
|
|
239
259
|
instance: DecoratedInstance,
|
|
@@ -250,6 +270,10 @@ class T::Props::Decorator
|
|
|
250
270
|
foreign_class.load(value, {}, opts)
|
|
251
271
|
end
|
|
252
272
|
|
|
273
|
+
# TODO: we should really be checking all the methods on `cls`, not just Object
|
|
274
|
+
BANNED_METHOD_NAMES = Object.instance_methods.to_set.freeze
|
|
275
|
+
|
|
276
|
+
# checked(:never) - Rules hash is expensive to check
|
|
253
277
|
sig do
|
|
254
278
|
params(
|
|
255
279
|
name: Symbol,
|
|
@@ -258,6 +282,7 @@ class T::Props::Decorator
|
|
|
258
282
|
type: PropTypeOrClass
|
|
259
283
|
)
|
|
260
284
|
.void
|
|
285
|
+
.checked(:never)
|
|
261
286
|
end
|
|
262
287
|
def prop_validate_definition!(name, cls, rules, type)
|
|
263
288
|
validate_prop_name(name)
|
|
@@ -267,7 +292,7 @@ class T::Props::Decorator
|
|
|
267
292
|
"to 'sensitivity:' (in prop #{@class.name}.#{name})")
|
|
268
293
|
end
|
|
269
294
|
|
|
270
|
-
if
|
|
295
|
+
if rules.keys.any? {|k| !valid_rule_key?(k)}
|
|
271
296
|
raise ArgumentError.new("At least one invalid prop arg supplied in #{self}: #{rules.keys.inspect}")
|
|
272
297
|
end
|
|
273
298
|
|
|
@@ -278,8 +303,7 @@ class T::Props::Decorator
|
|
|
278
303
|
end
|
|
279
304
|
|
|
280
305
|
if !(rules[:clobber_existing_method!]) && !(rules[:without_accessors])
|
|
281
|
-
|
|
282
|
-
if Object.instance_methods.include?(name.to_sym)
|
|
306
|
+
if BANNED_METHOD_NAMES.include?(name.to_sym)
|
|
283
307
|
raise ArgumentError.new(
|
|
284
308
|
"#{name} can't be used as a prop in #{@class} because a method with " \
|
|
285
309
|
"that name already exists (defined by #{@class.instance_method(name).owner} " \
|
|
@@ -303,13 +327,6 @@ class T::Props::Decorator
|
|
|
303
327
|
end
|
|
304
328
|
end
|
|
305
329
|
|
|
306
|
-
# Check if this cls represents a T.nilable(type)
|
|
307
|
-
sig {params(type: PropTypeOrClass).returns(T::Boolean)}
|
|
308
|
-
private def is_nilable?(type)
|
|
309
|
-
return false if !type.is_a?(T::Types::Union)
|
|
310
|
-
type.types.any? {|t| t == T::Utils.coerce(NilClass)}
|
|
311
|
-
end
|
|
312
|
-
|
|
313
330
|
# This converts the type from a T::Type to a regular old ruby class.
|
|
314
331
|
sig {params(type: T::Types::Base).returns(Module)}
|
|
315
332
|
private def convert_type_to_class(type)
|
|
@@ -338,6 +355,7 @@ class T::Props::Decorator
|
|
|
338
355
|
end
|
|
339
356
|
end
|
|
340
357
|
|
|
358
|
+
# checked(:never) - Rules hash is expensive to check
|
|
341
359
|
sig do
|
|
342
360
|
params(
|
|
343
361
|
name: T.any(Symbol, String),
|
|
@@ -345,6 +363,7 @@ class T::Props::Decorator
|
|
|
345
363
|
rules: Rules,
|
|
346
364
|
)
|
|
347
365
|
.void
|
|
366
|
+
.checked(:never)
|
|
348
367
|
end
|
|
349
368
|
def prop_defined(name, cls, rules={})
|
|
350
369
|
cls = T::Utils.resolve_alias(cls)
|
|
@@ -501,7 +520,8 @@ class T::Props::Decorator
|
|
|
501
520
|
handle_redaction_option(name, rules[:redaction]) if rules[:redaction]
|
|
502
521
|
end
|
|
503
522
|
|
|
504
|
-
|
|
523
|
+
# checked(:never) - Rules hash is expensive to check
|
|
524
|
+
sig {params(name: Symbol, rules: Rules).void.checked(:never)}
|
|
505
525
|
private def define_getter_and_setter(name, rules)
|
|
506
526
|
T::Configuration.without_ruby_warnings do
|
|
507
527
|
if !rules[:immutable]
|
|
@@ -510,16 +530,24 @@ class T::Props::Decorator
|
|
|
510
530
|
end
|
|
511
531
|
end
|
|
512
532
|
|
|
513
|
-
|
|
514
|
-
|
|
533
|
+
if method(:prop_get).owner != T::Props::Decorator || rules.key?(:ifunset)
|
|
534
|
+
@class.send(:define_method, name) do
|
|
535
|
+
self.class.decorator.prop_get(self, name, rules)
|
|
536
|
+
end
|
|
537
|
+
else
|
|
538
|
+
# Fast path (~30x faster as of Ruby 2.6)
|
|
539
|
+
@class.attr_reader(name)
|
|
515
540
|
end
|
|
516
541
|
end
|
|
517
542
|
end
|
|
518
543
|
|
|
519
544
|
# returns the subdoc of the array type, or nil if it's not a Document type
|
|
545
|
+
#
|
|
546
|
+
# checked(:never) - Typechecks internally
|
|
520
547
|
sig do
|
|
521
548
|
params(type: PropType)
|
|
522
549
|
.returns(T.nilable(Module))
|
|
550
|
+
.checked(:never)
|
|
523
551
|
end
|
|
524
552
|
private def array_subdoc_type(type)
|
|
525
553
|
if type.is_a?(T::Types::TypedArray)
|
|
@@ -535,9 +563,12 @@ class T::Props::Decorator
|
|
|
535
563
|
end
|
|
536
564
|
|
|
537
565
|
# returns the subdoc of the hash value type, or nil if it's not a Document type
|
|
566
|
+
#
|
|
567
|
+
# checked(:never) - Typechecks internally
|
|
538
568
|
sig do
|
|
539
569
|
params(type: PropType)
|
|
540
570
|
.returns(T.nilable(Module))
|
|
571
|
+
.checked(:never)
|
|
541
572
|
end
|
|
542
573
|
private def hash_value_subdoc_type(type)
|
|
543
574
|
if type.is_a?(T::Types::TypedHash)
|
|
@@ -553,9 +584,12 @@ class T::Props::Decorator
|
|
|
553
584
|
end
|
|
554
585
|
|
|
555
586
|
# returns the type of the hash key, or nil. Any CustomType could be a key, but we only expect T::Enum right now.
|
|
587
|
+
#
|
|
588
|
+
# checked(:never) - Typechecks internally
|
|
556
589
|
sig do
|
|
557
590
|
params(type: PropType)
|
|
558
591
|
.returns(T.nilable(Module))
|
|
592
|
+
.checked(:never)
|
|
559
593
|
end
|
|
560
594
|
private def hash_key_custom_type(type)
|
|
561
595
|
if type.is_a?(T::Types::TypedHash)
|
|
@@ -572,7 +606,8 @@ class T::Props::Decorator
|
|
|
572
606
|
# From T::Props::Utils.deep_clone_object, plus String
|
|
573
607
|
TYPES_NOT_NEEDING_CLONE = [TrueClass, FalseClass, NilClass, Symbol, String, Numeric]
|
|
574
608
|
|
|
575
|
-
|
|
609
|
+
# checked(:never) - Typechecks internally
|
|
610
|
+
sig {params(type: PropType).returns(T::Boolean).checked(:never)}
|
|
576
611
|
private def shallow_clone_ok(type)
|
|
577
612
|
inner_type =
|
|
578
613
|
if type.is_a?(T::Types::TypedArray)
|
|
@@ -613,7 +648,8 @@ class T::Props::Decorator
|
|
|
613
648
|
end
|
|
614
649
|
end
|
|
615
650
|
|
|
616
|
-
|
|
651
|
+
# checked(:never) - Rules hash is expensive to check
|
|
652
|
+
sig {params(prop_name: Symbol, rules: Hash).void.checked(:never)}
|
|
617
653
|
private def validate_not_missing_sensitivity(prop_name, rules)
|
|
618
654
|
if rules[:sensitivity].nil?
|
|
619
655
|
if rules[:redaction]
|
|
@@ -700,6 +736,7 @@ class T::Props::Decorator
|
|
|
700
736
|
)
|
|
701
737
|
end
|
|
702
738
|
|
|
739
|
+
# checked(:never) - Rules hash is expensive to check
|
|
703
740
|
sig do
|
|
704
741
|
params(
|
|
705
742
|
prop_name: T.any(String, Symbol),
|
|
@@ -707,6 +744,7 @@ class T::Props::Decorator
|
|
|
707
744
|
foreign: T.untyped,
|
|
708
745
|
)
|
|
709
746
|
.void
|
|
747
|
+
.checked(:never)
|
|
710
748
|
end
|
|
711
749
|
private def define_foreign_method(prop_name, rules, foreign)
|
|
712
750
|
fk_method = "#{prop_name}_"
|
|
@@ -758,6 +796,7 @@ class T::Props::Decorator
|
|
|
758
796
|
end
|
|
759
797
|
end
|
|
760
798
|
|
|
799
|
+
# checked(:never) - Rules hash is expensive to check
|
|
761
800
|
sig do
|
|
762
801
|
params(
|
|
763
802
|
prop_name: Symbol,
|
|
@@ -766,6 +805,7 @@ class T::Props::Decorator
|
|
|
766
805
|
foreign: T.untyped,
|
|
767
806
|
)
|
|
768
807
|
.void
|
|
808
|
+
.checked(:never)
|
|
769
809
|
end
|
|
770
810
|
private def handle_foreign_option(prop_name, prop_cls, rules, foreign)
|
|
771
811
|
validate_foreign_option(
|
|
@@ -793,7 +833,7 @@ class T::Props::Decorator
|
|
|
793
833
|
#
|
|
794
834
|
# This gets called when a module or class that extends T::Props gets included, extended,
|
|
795
835
|
# prepended, or inherited.
|
|
796
|
-
|
|
836
|
+
sig {params(child: DecoratedClass).void.checked(:never)}
|
|
797
837
|
def model_inherited(child)
|
|
798
838
|
child.extend(T::Props::ClassMethods)
|
|
799
839
|
child.plugins.concat(decorated_class.plugins)
|
|
@@ -811,10 +851,27 @@ class T::Props::Decorator
|
|
|
811
851
|
# time. Any class that defines props and also overrides the `decorator_class` method is going
|
|
812
852
|
# to reach this line before its override take effect, turning it into a no-op.
|
|
813
853
|
child.decorator.add_prop_definition(name, copied_rules)
|
|
854
|
+
|
|
855
|
+
# It's a bit tricky to support `prop_get` hooks added by plugins without
|
|
856
|
+
# sacrificing the `attr_reader` fast path or clobbering customized getters
|
|
857
|
+
# defined manually on a child.
|
|
858
|
+
#
|
|
859
|
+
# To make this work, we _do_ clobber getters defined on the child, but only if:
|
|
860
|
+
# (a) it's needed in order to support a `prop_get` hook, and
|
|
861
|
+
# (b) it's safe because the getter was defined by this file.
|
|
862
|
+
#
|
|
863
|
+
unless rules[:without_accessors]
|
|
864
|
+
if child.decorator.method(:prop_get).owner != method(:prop_get).owner &&
|
|
865
|
+
child.instance_method(name).source_location.first == __FILE__
|
|
866
|
+
child.send(:define_method, name) do
|
|
867
|
+
self.class.decorator.prop_get(self, name, rules)
|
|
868
|
+
end
|
|
869
|
+
end
|
|
870
|
+
end
|
|
814
871
|
end
|
|
815
872
|
end
|
|
816
873
|
|
|
817
|
-
|
|
874
|
+
sig {params(mod: Module).void.checked(:never)}
|
|
818
875
|
def plugin(mod)
|
|
819
876
|
decorated_class.plugins << mod
|
|
820
877
|
Private.apply_class_methods(mod, decorated_class)
|
data/lib/types/props/optional.rb
CHANGED
|
@@ -21,12 +21,15 @@ module T::Props::Optional::DecoratorMethods
|
|
|
21
21
|
true,
|
|
22
22
|
].freeze
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
VALID_RULE_KEYS = Set[
|
|
25
|
+
:default,
|
|
26
|
+
:factory,
|
|
27
|
+
:optional,
|
|
28
|
+
].freeze
|
|
29
|
+
private_constant :VALID_RULE_KEYS
|
|
30
|
+
|
|
31
|
+
def valid_rule_key?(key)
|
|
32
|
+
super || VALID_RULE_KEYS.include?(key)
|
|
30
33
|
end
|
|
31
34
|
|
|
32
35
|
def prop_optional?(prop); prop_rules(prop)[:fully_optional]; end
|
|
@@ -18,9 +18,9 @@ module T::Props::PrettyPrintable
|
|
|
18
18
|
module DecoratorMethods
|
|
19
19
|
extend T::Sig
|
|
20
20
|
|
|
21
|
-
sig {returns(T::
|
|
22
|
-
def
|
|
23
|
-
super
|
|
21
|
+
sig {params(key: Symbol).returns(T::Boolean).checked(:never)}
|
|
22
|
+
def valid_rule_key?(key)
|
|
23
|
+
super || key == :inspect
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
sig do
|
|
@@ -274,12 +274,12 @@ end
|
|
|
274
274
|
# NB: This must stay in the same file where T::Props::Serializable is defined due to
|
|
275
275
|
# 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
|
|
276
276
|
module T::Props::Serializable::DecoratorMethods
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
277
|
+
|
|
278
|
+
VALID_RULE_KEYS = Set[:dont_store, :name, :raise_on_nil_write].freeze
|
|
279
|
+
private_constant :VALID_RULE_KEYS
|
|
280
|
+
|
|
281
|
+
def valid_rule_key?(key)
|
|
282
|
+
super || VALID_RULE_KEYS.include?(key)
|
|
283
283
|
end
|
|
284
284
|
|
|
285
285
|
def required_props
|
|
@@ -11,9 +11,9 @@ module T::Props::TypeValidation
|
|
|
11
11
|
module DecoratorMethods
|
|
12
12
|
extend T::Sig
|
|
13
13
|
|
|
14
|
-
sig {returns(T::
|
|
15
|
-
def
|
|
16
|
-
super
|
|
14
|
+
sig {params(key: Symbol).returns(T::Boolean).checked(:never)}
|
|
15
|
+
def valid_rule_key?(key)
|
|
16
|
+
super || :DEPRECATED_underspecified_type == key
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
sig do
|
|
@@ -53,7 +53,9 @@ module T::Props::TypeValidation
|
|
|
53
53
|
# a subtype like the type of the values of a typed hash.
|
|
54
54
|
#
|
|
55
55
|
# If the type is fully valid, returns nil.
|
|
56
|
-
|
|
56
|
+
#
|
|
57
|
+
# checked(:never) - called potentially many times recursively
|
|
58
|
+
sig {params(type: T::Types::Base).returns(T.nilable(T::Types::Base)).checked(:never)}
|
|
57
59
|
private def find_invalid_subtype(type)
|
|
58
60
|
case type
|
|
59
61
|
when T::Types::TypedEnumerable
|
data/lib/types/utils.rb
CHANGED
|
@@ -96,7 +96,7 @@ module T::Utils
|
|
|
96
96
|
def self.unwrap_nilable(type)
|
|
97
97
|
case type
|
|
98
98
|
when T::Types::Union
|
|
99
|
-
non_nil_types = type.types.reject {|t| t ==
|
|
99
|
+
non_nil_types = type.types.reject {|t| t == Nilable::NIL_TYPE}
|
|
100
100
|
if non_nil_types.length == 1
|
|
101
101
|
non_nil_types.first
|
|
102
102
|
else
|
|
@@ -156,6 +156,8 @@ module T::Utils
|
|
|
156
156
|
# :non_nilable_type, Class: if it is an T.nilable type, the corresponding underlying type; otherwise, nil.
|
|
157
157
|
TypeInfo = Struct.new(:is_union_type, :non_nilable_type)
|
|
158
158
|
|
|
159
|
+
NIL_TYPE = T::Utils.coerce(NilClass)
|
|
160
|
+
|
|
159
161
|
def self.get_type_info(prop_type)
|
|
160
162
|
if prop_type.is_a?(T::Types::Union)
|
|
161
163
|
non_nilable_type = T::Utils.unwrap_nilable(prop_type)
|
|
@@ -191,7 +193,7 @@ module T::Utils
|
|
|
191
193
|
def self.is_union_with_nilclass(prop_type)
|
|
192
194
|
case prop_type
|
|
193
195
|
when T::Types::Union
|
|
194
|
-
prop_type.types.
|
|
196
|
+
prop_type.types.include?(NIL_TYPE)
|
|
195
197
|
else
|
|
196
198
|
false
|
|
197
199
|
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.5226
|
|
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-01-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: minitest
|