sorbet-runtime 0.5.6105 → 0.5.6130
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/types/configuration.rb +4 -4
- data/lib/types/non_forcing_constants.rb +1 -1
- data/lib/types/private/abstract/validate.rb +6 -6
- data/lib/types/private/methods/_methods.rb +8 -8
- data/lib/types/private/methods/call_validation.rb +2 -2
- data/lib/types/private/methods/modes.rb +3 -3
- data/lib/types/private/methods/signature.rb +5 -5
- data/lib/types/private/methods/signature_validation.rb +11 -14
- data/lib/types/private/sealed.rb +1 -1
- data/lib/types/props/decorator.rb +39 -36
- data/lib/types/props/generated_code_validation.rb +6 -6
- data/lib/types/props/has_lazily_specialized_methods.rb +1 -1
- data/lib/types/props/private/deserializer_generator.rb +3 -3
- data/lib/types/props/private/serde_transform.rb +11 -13
- data/lib/types/props/private/setter_factory.rb +3 -8
- data/lib/types/props/serializable.rb +5 -5
- data/lib/types/props/type_validation.rb +2 -2
- data/lib/types/types/fixed_hash.rb +1 -1
- data/lib/types/types/type_variable.rb +1 -1
- data/lib/types/types/typed_enumerable.rb +4 -4
- data/lib/types/utils.rb +1 -1
- 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: b2c6cd9c25bf625e725848fb66c990529af90f07966dbe94929b80ac62431de8
|
4
|
+
data.tar.gz: c20105ed1aa4b3aca71609d04c23f68776d6c6e6a1f63cb31475dfe81ea71434
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c5226fcd69dff48bf84fd1856b2368d8d222386da268d85b9bb8150cfd25f33301430bfa30b81f1f12e09b9298f6225ae807e4878746d2bf435aa01bb756743
|
7
|
+
data.tar.gz: a03c025907fe8e304504b78f064de0bc1acd9e8a3b500f5200c7af7e66a33ce3bcb489dc7868b5cf0fd873549c3d7ee0d30093191356c3d545c3baffdef67438
|
data/lib/types/configuration.rb
CHANGED
@@ -338,7 +338,7 @@ module T::Configuration
|
|
338
338
|
if values.nil?
|
339
339
|
@scalar_types = values
|
340
340
|
else
|
341
|
-
bad_values = values.
|
341
|
+
bad_values = values.reject {|v| v.class == String}
|
342
342
|
unless bad_values.empty?
|
343
343
|
raise ArgumentError.new("Provided values must all be class name strings.")
|
344
344
|
end
|
@@ -347,7 +347,7 @@ module T::Configuration
|
|
347
347
|
end
|
348
348
|
end
|
349
349
|
|
350
|
-
@default_scalar_types = Set.new(%w
|
350
|
+
@default_scalar_types = Set.new(%w[
|
351
351
|
NilClass
|
352
352
|
TrueClass
|
353
353
|
FalseClass
|
@@ -357,7 +357,7 @@ module T::Configuration
|
|
357
357
|
Symbol
|
358
358
|
Time
|
359
359
|
T::Enum
|
360
|
-
|
360
|
+
]).freeze
|
361
361
|
|
362
362
|
def self.scalar_types
|
363
363
|
@scalar_types || @default_scalar_types
|
@@ -398,7 +398,7 @@ module T::Configuration
|
|
398
398
|
# should be allowed. Useful to whitelist benign violations, like shim files
|
399
399
|
# generated for an autoloader.
|
400
400
|
def self.sealed_violation_whitelist=(sealed_violation_whitelist)
|
401
|
-
if
|
401
|
+
if !@sealed_violation_whitelist.nil?
|
402
402
|
raise ArgumentError.new("Cannot overwrite sealed_violation_whitelist after setting it")
|
403
403
|
end
|
404
404
|
|
@@ -111,16 +111,16 @@ module T::Private::Abstract::Validate
|
|
111
111
|
end
|
112
112
|
|
113
113
|
private_class_method def self.describe_method(method, show_owner: true)
|
114
|
-
if method.source_location
|
115
|
-
|
114
|
+
loc = if method.source_location
|
115
|
+
method.source_location.join(':')
|
116
116
|
else
|
117
|
-
|
117
|
+
"<unknown location>"
|
118
118
|
end
|
119
119
|
|
120
|
-
if show_owner
|
121
|
-
|
120
|
+
owner = if show_owner
|
121
|
+
" declared in #{method.owner}"
|
122
122
|
else
|
123
|
-
|
123
|
+
""
|
124
124
|
end
|
125
125
|
|
126
126
|
" * `#{method.name}`#{owner} at #{loc}"
|
@@ -145,7 +145,7 @@ module T::Private::Methods
|
|
145
145
|
if (ancestor.method_defined?(method_name) ||
|
146
146
|
ancestor.private_method_defined?(method_name) ||
|
147
147
|
ancestor.protected_method_defined?(method_name)) &&
|
148
|
-
|
148
|
+
final_method?(method_owner_and_name_to_key(ancestor, method_name))
|
149
149
|
raise(
|
150
150
|
"The method `#{method_name}` on #{ancestor} was declared as final and cannot be " +
|
151
151
|
(target == ancestor ? "redefined" : "overridden in #{target}")
|
@@ -193,7 +193,7 @@ module T::Private::Methods
|
|
193
193
|
|
194
194
|
if method_name == :method_added || method_name == :singleton_method_added
|
195
195
|
raise(
|
196
|
-
"Putting a `sig` on `#{method_name}` is not supported"
|
196
|
+
"Putting a `sig` on `#{method_name}` is not supported" \
|
197
197
|
" (sorbet-runtime uses this method internally to perform `sig` validation logic)"
|
198
198
|
)
|
199
199
|
end
|
@@ -316,10 +316,10 @@ module T::Private::Methods
|
|
316
316
|
begin
|
317
317
|
# We allow `sig` in the current module's context (normal case) and
|
318
318
|
if hook_mod != current_declaration.mod &&
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
319
|
+
# inside `class << self`, and
|
320
|
+
hook_mod.singleton_class != current_declaration.mod &&
|
321
|
+
# on `self` at the top level of a file
|
322
|
+
current_declaration.mod != TOP_SELF
|
323
323
|
raise "A method (#{method_name}) is being added on a different class/module (#{hook_mod}) than the " \
|
324
324
|
"last call to `sig` (#{current_declaration.mod}). Make sure each call " \
|
325
325
|
"to `sig` is immediately followed by a method definition on the same " \
|
@@ -410,7 +410,7 @@ module T::Private::Methods
|
|
410
410
|
def self.run_all_sig_blocks
|
411
411
|
loop do
|
412
412
|
break if @sig_wrappers.empty?
|
413
|
-
key,
|
413
|
+
key, = @sig_wrappers.first
|
414
414
|
run_sig_block_for_key(key)
|
415
415
|
end
|
416
416
|
end
|
@@ -427,7 +427,7 @@ module T::Private::Methods
|
|
427
427
|
end
|
428
428
|
|
429
429
|
def self.set_final_checks_on_hooks(enable)
|
430
|
-
is_enabled =
|
430
|
+
is_enabled = !@old_hooks.nil?
|
431
431
|
if enable == is_enabled
|
432
432
|
return
|
433
433
|
end
|
@@ -195,7 +195,7 @@ module T::Private::Methods::CallValidation
|
|
195
195
|
raise "Should have used create_validator_procedure_fast"
|
196
196
|
end
|
197
197
|
# trampoline to reduce stack frame size
|
198
|
-
if method_sig.arg_types.
|
198
|
+
if method_sig.arg_types.empty?
|
199
199
|
create_validator_method_fast0(mod, original_method, method_sig, method_sig.return_type.raw_type)
|
200
200
|
elsif method_sig.arg_types.length == 1
|
201
201
|
create_validator_method_fast1(mod, original_method, method_sig, method_sig.return_type.raw_type,
|
@@ -708,7 +708,7 @@ module T::Private::Methods::CallValidation
|
|
708
708
|
|
709
709
|
def self.create_validator_procedure_fast(mod, original_method, method_sig)
|
710
710
|
# trampoline to reduce stack frame size
|
711
|
-
if method_sig.arg_types.
|
711
|
+
if method_sig.arg_types.empty?
|
712
712
|
create_validator_procedure_fast0(mod, original_method, method_sig)
|
713
713
|
elsif method_sig.arg_types.length == 1
|
714
714
|
create_validator_procedure_fast1(mod, original_method, method_sig,
|
@@ -8,9 +8,9 @@ module T::Private::Methods::Modes
|
|
8
8
|
def self.override; 'override'; end
|
9
9
|
def self.overridable_override; 'overridable_override'; end
|
10
10
|
def self.untyped; 'untyped'; end
|
11
|
-
MODES = [self.standard, self.abstract, self.overridable, self.override, self.overridable_override, self.untyped]
|
11
|
+
MODES = [self.standard, self.abstract, self.overridable, self.override, self.overridable_override, self.untyped].freeze
|
12
12
|
|
13
|
-
OVERRIDABLE_MODES = [self.override, self.overridable, self.overridable_override, self.untyped, self.abstract]
|
14
|
-
OVERRIDE_MODES = [self.override, self.overridable_override]
|
13
|
+
OVERRIDABLE_MODES = [self.override, self.overridable, self.overridable_override, self.untyped, self.abstract].freeze
|
14
|
+
OVERRIDE_MODES = [self.override, self.overridable_override].freeze
|
15
15
|
NON_OVERRIDE_MODES = MODES - OVERRIDE_MODES
|
16
16
|
end
|
@@ -28,7 +28,7 @@ class T::Private::Methods::Signature
|
|
28
28
|
)
|
29
29
|
end
|
30
30
|
|
31
|
-
def initialize(method:, method_name:, raw_arg_types:, raw_return_type:, bind:, mode:, check_level:, parameters: method.parameters,
|
31
|
+
def initialize(method:, method_name:, raw_arg_types:, raw_return_type:, bind:, mode:, check_level:, on_failure:, parameters: method.parameters, override_allow_incompatible: false)
|
32
32
|
@method = method
|
33
33
|
@method_name = method_name
|
34
34
|
@arg_types = []
|
@@ -67,7 +67,7 @@ class T::Private::Methods::Signature
|
|
67
67
|
if !extra_names.empty?
|
68
68
|
raise "The declaration for `#{method.name}` has extra parameter(s): #{extra_names.join(', ')}"
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
if parameters.size != raw_arg_types.size
|
72
72
|
raise "The declaration for `#{method.name}` has arguments with duplicate names"
|
73
73
|
end
|
@@ -198,10 +198,10 @@ class T::Private::Methods::Signature
|
|
198
198
|
end
|
199
199
|
|
200
200
|
def method_desc
|
201
|
-
if @method.source_location
|
202
|
-
|
201
|
+
loc = if @method.source_location
|
202
|
+
@method.source_location.join(':')
|
203
203
|
else
|
204
|
-
|
204
|
+
"<unknown location>"
|
205
205
|
end
|
206
206
|
"#{@method} at #{loc}"
|
207
207
|
end
|
@@ -100,19 +100,16 @@ module T::Private::Methods::SignatureValidation
|
|
100
100
|
raise "Unexpected mode: #{signature.mode}. Please report to #dev-productivity."
|
101
101
|
end
|
102
102
|
|
103
|
+
# Given a singleton class, we can check if it belongs to a
|
104
|
+
# module by looking at its superclass; given `module M`,
|
105
|
+
# `M.singleton_class.superclass == Module`, which is not true
|
106
|
+
# for any class.
|
103
107
|
owner = signature.method.owner
|
104
108
|
if (signature.mode == Modes.abstract || Modes::OVERRIDABLE_MODES.include?(signature.mode)) &&
|
105
|
-
owner.singleton_class?
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
# for any class.
|
110
|
-
if owner.superclass == Module
|
111
|
-
raise "Defining an overridable class method (via #{pretty_mode(signature)}) " \
|
112
|
-
"on a module is not allowed. Class methods on " \
|
113
|
-
"modules do not get inherited and thus cannot be overridden. For help, ask in " \
|
114
|
-
"#dev-productivity."
|
115
|
-
end
|
109
|
+
owner.singleton_class? && owner.superclass == Module
|
110
|
+
raise "Defining an overridable class method (via #{pretty_mode(signature)}) " \
|
111
|
+
"on a module is not allowed. Class methods on " \
|
112
|
+
"modules do not get inherited and thus cannot be overridden."
|
116
113
|
end
|
117
114
|
end
|
118
115
|
|
@@ -219,10 +216,10 @@ module T::Private::Methods::SignatureValidation
|
|
219
216
|
end
|
220
217
|
|
221
218
|
private_class_method def self.method_loc_str(method)
|
222
|
-
if method.source_location
|
223
|
-
|
219
|
+
loc = if method.source_location
|
220
|
+
method.source_location.join(':')
|
224
221
|
else
|
225
|
-
|
222
|
+
"<unknown location>"
|
226
223
|
end
|
227
224
|
"#{method.owner} at #{loc}"
|
228
225
|
end
|
data/lib/types/private/sealed.rb
CHANGED
@@ -70,7 +70,7 @@ module T::Private::Sealed
|
|
70
70
|
|
71
71
|
if !this_file.start_with?(decl_file)
|
72
72
|
whitelist = T::Configuration.sealed_violation_whitelist
|
73
|
-
if whitelist
|
73
|
+
if !whitelist.nil? && whitelist.any? {|pattern| this_file =~ pattern}
|
74
74
|
return
|
75
75
|
end
|
76
76
|
|
@@ -54,7 +54,7 @@ class T::Props::Decorator
|
|
54
54
|
@props = @props.merge(prop => rules.freeze).freeze
|
55
55
|
end
|
56
56
|
|
57
|
-
VALID_RULE_KEYS = T.let(%i
|
57
|
+
VALID_RULE_KEYS = T.let(%i[
|
58
58
|
enum
|
59
59
|
foreign
|
60
60
|
foreign_hint_only
|
@@ -68,7 +68,7 @@ class T::Props::Decorator
|
|
68
68
|
extra
|
69
69
|
setter_validate
|
70
70
|
_tnilable
|
71
|
-
|
71
|
+
].map {|k| [k, true]}.to_h.freeze, T::Hash[Symbol, T::Boolean])
|
72
72
|
private_constant :VALID_RULE_KEYS
|
73
73
|
|
74
74
|
sig {params(key: Symbol).returns(T::Boolean).checked(:never)}
|
@@ -153,12 +153,10 @@ class T::Props::Decorator
|
|
153
153
|
val = instance.instance_variable_get(rules[:accessor_key])
|
154
154
|
if !val.nil?
|
155
155
|
val
|
156
|
+
elsif (d = rules[:ifunset])
|
157
|
+
T::Props::Utils.deep_clone_object(d)
|
156
158
|
else
|
157
|
-
|
158
|
-
T::Props::Utils.deep_clone_object(d)
|
159
|
-
else
|
160
|
-
nil
|
161
|
-
end
|
159
|
+
nil
|
162
160
|
end
|
163
161
|
end
|
164
162
|
|
@@ -219,15 +217,13 @@ class T::Props::Decorator
|
|
219
217
|
raise ArgumentError.new("At least one invalid prop arg supplied in #{self}: #{rules.keys.inspect}")
|
220
218
|
end
|
221
219
|
|
222
|
-
if !
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
)
|
230
|
-
end
|
220
|
+
if !rules[:clobber_existing_method!] && !rules[:without_accessors] && BANNED_METHOD_NAMES.include?(name.to_sym)
|
221
|
+
raise ArgumentError.new(
|
222
|
+
"#{name} can't be used as a prop in #{@class} because a method with " \
|
223
|
+
"that name already exists (defined by #{@class.instance_method(name).owner} " \
|
224
|
+
"at #{@class.instance_method(name).source_location || '<unknown>'}). " \
|
225
|
+
"(If using this name is unavoidable, try `without_accessors: true`.)"
|
226
|
+
)
|
231
227
|
end
|
232
228
|
|
233
229
|
extra = rules[:extra]
|
@@ -238,7 +234,7 @@ class T::Props::Decorator
|
|
238
234
|
nil
|
239
235
|
end
|
240
236
|
|
241
|
-
SAFE_NAME = /\A[A-Za-z_][A-Za-z0-9_-]*\z
|
237
|
+
SAFE_NAME = T.let(/\A[A-Za-z_][A-Za-z0-9_-]*\z/.freeze, Regexp)
|
242
238
|
|
243
239
|
# Used to validate both prop names and serialized forms
|
244
240
|
sig {params(name: T.any(Symbol, String)).void}
|
@@ -312,13 +308,12 @@ class T::Props::Decorator
|
|
312
308
|
sensitivity_and_pii = {sensitivity: rules[:sensitivity]}
|
313
309
|
if defined?(Opus) && defined?(Opus::Sensitivity) && defined?(Opus::Sensitivity::Utils)
|
314
310
|
sensitivity_and_pii = Opus::Sensitivity::Utils.normalize_sensitivity_and_pii_annotation(sensitivity_and_pii)
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
if defined?(Opus) && defined?(Opus::Sensitivity) && defined?(Opus::Sensitivity::PIIable)
|
311
|
+
|
312
|
+
# We check for Class so this is only applied on concrete
|
313
|
+
# documents/models; We allow mixins containing props to not
|
314
|
+
# specify their PII nature, as long as every class into which they
|
315
|
+
# are ultimately included does.
|
316
|
+
#
|
322
317
|
if sensitivity_and_pii[:pii] && @class.is_a?(Class) && !T.unsafe(@class).contains_pii?
|
323
318
|
raise ArgumentError.new(
|
324
319
|
'Cannot include a pii prop in a class that declares `contains_no_pii`'
|
@@ -488,7 +483,7 @@ class T::Props::Decorator
|
|
488
483
|
.void
|
489
484
|
end
|
490
485
|
private def handle_foreign_hint_only_option(prop_name, prop_cls, foreign_hint_only)
|
491
|
-
if ![String, Array].include?(prop_cls) && !
|
486
|
+
if ![String, Array].include?(prop_cls) && !prop_cls.is_a?(T::Props::CustomType)
|
492
487
|
raise ArgumentError.new(
|
493
488
|
"`foreign_hint_only` can only be used with String or Array prop types"
|
494
489
|
)
|
@@ -546,10 +541,10 @@ class T::Props::Decorator
|
|
546
541
|
# of the method, optimizing it so this only runs on the first invocation.
|
547
542
|
foreign = resolved_foreign
|
548
543
|
end
|
549
|
-
if allow_direct_mutation.nil?
|
550
|
-
|
544
|
+
opts = if allow_direct_mutation.nil?
|
545
|
+
{}
|
551
546
|
else
|
552
|
-
|
547
|
+
{allow_direct_mutation: allow_direct_mutation}
|
553
548
|
end
|
554
549
|
|
555
550
|
T.unsafe(self.class).decorator.foreign_prop_get(self, prop_name, foreign, rules, opts)
|
@@ -644,25 +639,33 @@ class T::Props::Decorator
|
|
644
639
|
# (b) it's safe because the getter was defined by this file.
|
645
640
|
#
|
646
641
|
unless rules[:without_accessors]
|
647
|
-
if child
|
648
|
-
child.instance_method(name).source_location&.first == __FILE__
|
642
|
+
if clobber_getter?(child, name)
|
649
643
|
child.send(:define_method, name) do
|
650
644
|
T.unsafe(self.class).decorator.prop_get(self, name, rules)
|
651
645
|
end
|
652
646
|
end
|
653
647
|
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
child.send(:define_method, "#{name}=") do |val|
|
658
|
-
T.unsafe(self.class).decorator.prop_set(self, name, val, rules)
|
659
|
-
end
|
648
|
+
if !rules[:immutable] && clobber_setter?(child, name)
|
649
|
+
child.send(:define_method, "#{name}=") do |val|
|
650
|
+
T.unsafe(self.class).decorator.prop_set(self, name, val, rules)
|
660
651
|
end
|
661
652
|
end
|
662
653
|
end
|
663
654
|
end
|
664
655
|
end
|
665
656
|
|
657
|
+
sig {params(child: T.all(Module, T::Props::ClassMethods), prop: Symbol).returns(T::Boolean).checked(:never)}
|
658
|
+
private def clobber_getter?(child, prop)
|
659
|
+
!!(child.decorator.method(:prop_get).owner != method(:prop_get).owner &&
|
660
|
+
child.instance_method(prop).source_location&.first == __FILE__)
|
661
|
+
end
|
662
|
+
|
663
|
+
sig {params(child: T.all(Module, T::Props::ClassMethods), prop: Symbol).returns(T::Boolean).checked(:never)}
|
664
|
+
private def clobber_setter?(child, prop)
|
665
|
+
!!(child.decorator.method(:prop_set).owner != method(:prop_set).owner &&
|
666
|
+
child.instance_method("#{prop}=").source_location&.first == __FILE__)
|
667
|
+
end
|
668
|
+
|
666
669
|
sig {params(mod: Module).void.checked(:never)}
|
667
670
|
def plugin(mod)
|
668
671
|
decorated_class.plugins << mod
|
@@ -38,7 +38,7 @@ module T::Props
|
|
38
38
|
assert_equal(s(:lvar, :found), ret)
|
39
39
|
|
40
40
|
prop_clauses.each_with_index do |clause, i|
|
41
|
-
if i
|
41
|
+
if i.even?
|
42
42
|
validate_deserialize_hash_read(clause)
|
43
43
|
else
|
44
44
|
validate_deserialize_ivar_set(clause)
|
@@ -251,17 +251,17 @@ module T::Props
|
|
251
251
|
# Method calls generated by SerdeTransform
|
252
252
|
private_class_method def self.whitelisted_methods_for_serialize
|
253
253
|
@whitelisted_methods_for_serialize ||= {
|
254
|
-
:
|
255
|
-
:
|
256
|
-
:
|
254
|
+
lvar: %i{dup map transform_values transform_keys each_with_object nil? []= serialize},
|
255
|
+
ivar: %i[dup map transform_values transform_keys each_with_object serialize],
|
256
|
+
const: %i[checked_serialize deep_clone_object],
|
257
257
|
}
|
258
258
|
end
|
259
259
|
|
260
260
|
# Method calls generated by SerdeTransform
|
261
261
|
private_class_method def self.whitelisted_methods_for_deserialize
|
262
262
|
@whitelisted_methods_for_deserialize ||= {
|
263
|
-
:
|
264
|
-
:
|
263
|
+
lvar: %i{dup map transform_values transform_keys each_with_object nil? []= to_f},
|
264
|
+
const: %i[deserialize from_hash deep_clone_object soft_assert_handler],
|
265
265
|
}
|
266
266
|
end
|
267
267
|
end
|
@@ -48,12 +48,12 @@ module T::Props
|
|
48
48
|
SerdeTransform::Mode::DESERIALIZE,
|
49
49
|
'val'
|
50
50
|
)
|
51
|
-
if transformation
|
51
|
+
transformed_val = if transformation
|
52
52
|
# Rescuing exactly NoMethodError is intended as a temporary hack
|
53
53
|
# to preserve the semantics from before codegen. More generally
|
54
54
|
# we are inconsistent about typechecking on deser and need to decide
|
55
55
|
# our strategy here.
|
56
|
-
|
56
|
+
<<~RUBY
|
57
57
|
begin
|
58
58
|
#{transformation}
|
59
59
|
rescue NoMethodError => e
|
@@ -71,7 +71,7 @@ module T::Props
|
|
71
71
|
end
|
72
72
|
RUBY
|
73
73
|
else
|
74
|
-
|
74
|
+
'val'
|
75
75
|
end
|
76
76
|
|
77
77
|
nil_handler = generate_nil_handler(
|
@@ -99,20 +99,18 @@ module T::Props
|
|
99
99
|
else
|
100
100
|
"#{varname}.nil? ? nil : #{inner}"
|
101
101
|
end
|
102
|
-
|
102
|
+
elsif type.types.all? {|t| generate(t, mode, varname).nil?}
|
103
103
|
# Handle, e.g., T::Boolean
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
"T::Props::Utils.deep_clone_object(#{varname})"
|
115
|
-
end
|
104
|
+
nil
|
105
|
+
else
|
106
|
+
# We currently deep_clone_object if the type was T.any(Integer, Float).
|
107
|
+
# When we get better support for union types (maybe this specific
|
108
|
+
# union type, because it would be a replacement for
|
109
|
+
# Chalk::ODM::DeprecatedNumemric), we could opt to special case
|
110
|
+
# this union to have no specific serde transform (the only reason
|
111
|
+
# why Float has a special case is because round tripping through
|
112
|
+
# JSON might normalize Floats to Integers)
|
113
|
+
"T::Props::Utils.deep_clone_object(#{varname})"
|
116
114
|
end
|
117
115
|
when T::Types::Intersection
|
118
116
|
dynamic_fallback = "T::Props::Utils.deep_clone_object(#{varname})"
|
@@ -58,10 +58,7 @@ module T::Props
|
|
58
58
|
# from disk) are correct, so we use more thorough runtime
|
59
59
|
# checks there
|
60
60
|
if non_nil_type.recursively_valid?(val)
|
61
|
-
|
62
|
-
validate.call(prop, val)
|
63
|
-
end
|
64
|
-
instance_variable_set(accessor_key, val)
|
61
|
+
validate&.call(prop, val)
|
65
62
|
else
|
66
63
|
T::Props::Private::SetterFactory.raise_pretty_error(
|
67
64
|
klass,
|
@@ -69,8 +66,8 @@ module T::Props
|
|
69
66
|
non_nil_type,
|
70
67
|
val,
|
71
68
|
)
|
72
|
-
instance_variable_set(accessor_key, val)
|
73
69
|
end
|
70
|
+
instance_variable_set(accessor_key, val)
|
74
71
|
end
|
75
72
|
end
|
76
73
|
|
@@ -94,9 +91,7 @@ module T::Props
|
|
94
91
|
# from disk) are correct, so we use more thorough runtime
|
95
92
|
# checks there
|
96
93
|
elsif non_nil_type.recursively_valid?(val)
|
97
|
-
|
98
|
-
validate.call(prop, val)
|
99
|
-
end
|
94
|
+
validate&.call(prop, val)
|
100
95
|
instance_variable_set(accessor_key, val)
|
101
96
|
else
|
102
97
|
T::Props::Private::SetterFactory.raise_pretty_error(
|
@@ -15,7 +15,7 @@ module T::Props::Serializable
|
|
15
15
|
# exception if this object has mandatory props with missing
|
16
16
|
# values.
|
17
17
|
# @return [Hash] A serialization of this object.
|
18
|
-
def serialize(strict=true)
|
18
|
+
def serialize(strict=true) # rubocop:disable Style/OptionalBooleanParameter (changing this API is unfortunately not feasible)
|
19
19
|
begin
|
20
20
|
h = __t_props_generated_serialize(strict)
|
21
21
|
rescue => e
|
@@ -56,7 +56,7 @@ module T::Props::Serializable
|
|
56
56
|
# the hash contains keys that do not correspond to any known
|
57
57
|
# props on this instance.
|
58
58
|
# @return [void]
|
59
|
-
def deserialize(hash, strict=false)
|
59
|
+
def deserialize(hash, strict=false) # rubocop:disable Style/OptionalBooleanParameter (changing this API is unfortunately not feasible)
|
60
60
|
begin
|
61
61
|
hash_keys_matching_props = __t_props_generated_deserialize(hash)
|
62
62
|
rescue => e
|
@@ -180,7 +180,7 @@ module T::Props::Serializable::DecoratorMethods
|
|
180
180
|
def prop_dont_store?(prop); prop_rules(prop)[:dont_store]; end
|
181
181
|
def prop_by_serialized_forms; @class.prop_by_serialized_forms; end
|
182
182
|
|
183
|
-
def from_hash(hash, strict=false)
|
183
|
+
def from_hash(hash, strict=false) # rubocop:disable Style/OptionalBooleanParameter (changing this API is unfortunately not feasible)
|
184
184
|
raise ArgumentError.new("#{hash.inspect} provided to from_hash") if !(hash && hash.is_a?(Hash))
|
185
185
|
|
186
186
|
i = @class.allocate
|
@@ -227,7 +227,7 @@ module T::Props::Serializable::DecoratorMethods
|
|
227
227
|
source_lines = self.send(generate_source_method).split("\n")
|
228
228
|
previous_blank = source_lines[0...line_num].rindex(&:empty?) || 0
|
229
229
|
next_blank = line_num + (source_lines[line_num..-1]&.find_index(&:empty?) || 0)
|
230
|
-
context = "
|
230
|
+
context = " #{source_lines[(previous_blank + 1)...next_blank].join("\n ")}"
|
231
231
|
<<~MSG
|
232
232
|
Error in #{decorated_class.name}##{generated_method}: #{error.message}
|
233
233
|
at line #{line_num-previous_blank-1} in:
|
@@ -318,7 +318,7 @@ module T::Props::Serializable::ClassMethods
|
|
318
318
|
# Allocate a new instance and call {#deserialize} to load a new
|
319
319
|
# object from a hash.
|
320
320
|
# @return [Serializable]
|
321
|
-
def from_hash(hash, strict=false)
|
321
|
+
def from_hash(hash, strict=false) # rubocop:disable Style/OptionalBooleanParameter (changing this API is unfortunately not feasible)
|
322
322
|
self.decorator.from_hash(hash, strict)
|
323
323
|
end
|
324
324
|
|
@@ -4,7 +4,7 @@
|
|
4
4
|
module T::Props::TypeValidation
|
5
5
|
include T::Props::Plugin
|
6
6
|
|
7
|
-
BANNED_TYPES = [Object, BasicObject, Kernel]
|
7
|
+
BANNED_TYPES = [Object, BasicObject, Kernel].freeze
|
8
8
|
|
9
9
|
class UnderspecifiedType < ArgumentError; end
|
10
10
|
|
@@ -13,7 +13,7 @@ module T::Props::TypeValidation
|
|
13
13
|
|
14
14
|
sig {params(key: Symbol).returns(T::Boolean).checked(:never)}
|
15
15
|
def valid_rule_key?(key)
|
16
|
-
super ||
|
16
|
+
super || key == :DEPRECATED_underspecified_type
|
17
17
|
end
|
18
18
|
|
19
19
|
sig do
|
@@ -37,7 +37,7 @@ module T::Types
|
|
37
37
|
return false unless @type.recursively_valid?(obj[it])
|
38
38
|
it += 1
|
39
39
|
end
|
40
|
-
|
40
|
+
true
|
41
41
|
end
|
42
42
|
when Hash
|
43
43
|
return false unless @type.is_a?(FixedArray)
|
@@ -50,10 +50,10 @@ module T::Types
|
|
50
50
|
# iterate over a [key, value] array, so we can't juse use the @type.recursively_valid?(v)
|
51
51
|
return false if !key_type.recursively_valid?(key) || !value_type.recursively_valid?(val)
|
52
52
|
end
|
53
|
-
|
53
|
+
true
|
54
54
|
when Enumerator
|
55
55
|
# Enumerators can be unbounded: see `[:foo, :bar].cycle`
|
56
|
-
|
56
|
+
true
|
57
57
|
when Range
|
58
58
|
# A nil beginning or a nil end does not provide any type information. That is, nil in a range represents
|
59
59
|
# boundlessness, it does not express a type. For example `(nil...nil)` is not a T::Range[NilClass], its a range
|
@@ -65,7 +65,7 @@ module T::Types
|
|
65
65
|
return false unless @type.recursively_valid?(item)
|
66
66
|
end
|
67
67
|
|
68
|
-
|
68
|
+
true
|
69
69
|
else
|
70
70
|
# We don't check the enumerable since it isn't guaranteed to be
|
71
71
|
# rewindable (e.g. STDIN) and it may be expensive to enumerate
|
data/lib/types/utils.rb
CHANGED
@@ -176,7 +176,7 @@ module T::Utils
|
|
176
176
|
def self.get_type_info(prop_type)
|
177
177
|
if prop_type.is_a?(T::Types::Union)
|
178
178
|
non_nilable_type = T::Utils.unwrap_nilable(prop_type)
|
179
|
-
if non_nilable_type
|
179
|
+
if non_nilable_type&.is_a?(T::Types::Simple)
|
180
180
|
non_nilable_type = non_nilable_type.raw_type
|
181
181
|
end
|
182
182
|
TypeInfo.new(true, non_nilable_type)
|
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.6130
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stripe
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|