sorbet-runtime 0.5.10439 → 0.5.11120
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 +7 -1
- data/lib/types/_types.rb +57 -3
- data/lib/types/compatibility_patches.rb +4 -2
- data/lib/types/enum.rb +6 -1
- data/lib/types/generic.rb +2 -0
- data/lib/types/private/abstract/declare.rb +10 -9
- data/lib/types/private/casts.rb +4 -1
- data/lib/types/private/class_utils.rb +13 -6
- data/lib/types/private/methods/_methods.rb +37 -12
- data/lib/types/private/methods/call_validation.rb +104 -5
- data/lib/types/private/methods/call_validation_2_6.rb +68 -60
- data/lib/types/private/methods/call_validation_2_7.rb +68 -60
- data/lib/types/private/methods/decl_builder.rb +21 -6
- data/lib/types/private/methods/signature.rb +63 -38
- data/lib/types/private/methods/signature_validation.rb +68 -6
- data/lib/types/private/runtime_levels.rb +19 -0
- data/lib/types/private/types/not_typed.rb +2 -0
- data/lib/types/private/types/simple_pair_union.rb +55 -0
- data/lib/types/private/types/void.rb +29 -23
- data/lib/types/props/_props.rb +2 -2
- data/lib/types/props/custom_type.rb +2 -2
- data/lib/types/props/decorator.rb +41 -36
- data/lib/types/props/has_lazily_specialized_methods.rb +2 -2
- data/lib/types/props/pretty_printable.rb +45 -83
- data/lib/types/props/private/setter_factory.rb +1 -1
- data/lib/types/props/serializable.rb +17 -9
- data/lib/types/props/type_validation.rb +5 -2
- data/lib/types/struct.rb +2 -2
- data/lib/types/types/anything.rb +31 -0
- data/lib/types/types/base.rb +15 -1
- data/lib/types/types/class_of.rb +11 -0
- data/lib/types/types/enum.rb +1 -1
- data/lib/types/types/fixed_array.rb +13 -0
- data/lib/types/types/fixed_hash.rb +22 -0
- data/lib/types/types/intersection.rb +1 -1
- data/lib/types/types/noreturn.rb +0 -1
- data/lib/types/types/simple.rb +27 -4
- data/lib/types/types/type_parameter.rb +19 -0
- data/lib/types/types/typed_array.rb +29 -0
- data/lib/types/types/typed_class.rb +85 -0
- data/lib/types/types/typed_enumerable.rb +7 -0
- data/lib/types/types/typed_enumerator_chain.rb +41 -0
- data/lib/types/types/union.rb +50 -14
- data/lib/types/utils.rb +41 -33
- metadata +14 -10
@@ -11,26 +11,28 @@ module T::Private::Methods::CallValidation
|
|
11
11
|
raise 'Should have used create_validator_procedure_fast'
|
12
12
|
end
|
13
13
|
# trampoline to reduce stack frame size
|
14
|
-
|
14
|
+
arg_types = method_sig.arg_types
|
15
|
+
case arg_types.length
|
16
|
+
when 0
|
15
17
|
create_validator_method_fast0(mod, original_method, method_sig, original_visibility, method_sig.return_type.raw_type)
|
16
|
-
|
18
|
+
when 1
|
17
19
|
create_validator_method_fast1(mod, original_method, method_sig, original_visibility, method_sig.return_type.raw_type,
|
18
|
-
|
19
|
-
|
20
|
+
arg_types[0][1].raw_type)
|
21
|
+
when 2
|
20
22
|
create_validator_method_fast2(mod, original_method, method_sig, original_visibility, method_sig.return_type.raw_type,
|
21
|
-
|
22
|
-
|
23
|
-
|
23
|
+
arg_types[0][1].raw_type,
|
24
|
+
arg_types[1][1].raw_type)
|
25
|
+
when 3
|
24
26
|
create_validator_method_fast3(mod, original_method, method_sig, original_visibility, method_sig.return_type.raw_type,
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
arg_types[0][1].raw_type,
|
28
|
+
arg_types[1][1].raw_type,
|
29
|
+
arg_types[2][1].raw_type)
|
30
|
+
when 4
|
29
31
|
create_validator_method_fast4(mod, original_method, method_sig, original_visibility, method_sig.return_type.raw_type,
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
32
|
+
arg_types[0][1].raw_type,
|
33
|
+
arg_types[1][1].raw_type,
|
34
|
+
arg_types[2][1].raw_type,
|
35
|
+
arg_types[3][1].raw_type)
|
34
36
|
else
|
35
37
|
raise 'should not happen'
|
36
38
|
end
|
@@ -343,26 +345,28 @@ module T::Private::Methods::CallValidation
|
|
343
345
|
|
344
346
|
def self.create_validator_procedure_fast(mod, original_method, method_sig, original_visibility)
|
345
347
|
# trampoline to reduce stack frame size
|
346
|
-
|
348
|
+
arg_types = method_sig.arg_types
|
349
|
+
case arg_types.length
|
350
|
+
when 0
|
347
351
|
create_validator_procedure_fast0(mod, original_method, method_sig, original_visibility)
|
348
|
-
|
352
|
+
when 1
|
349
353
|
create_validator_procedure_fast1(mod, original_method, method_sig, original_visibility,
|
350
|
-
|
351
|
-
|
354
|
+
arg_types[0][1].raw_type)
|
355
|
+
when 2
|
352
356
|
create_validator_procedure_fast2(mod, original_method, method_sig, original_visibility,
|
353
|
-
|
354
|
-
|
355
|
-
|
357
|
+
arg_types[0][1].raw_type,
|
358
|
+
arg_types[1][1].raw_type)
|
359
|
+
when 3
|
356
360
|
create_validator_procedure_fast3(mod, original_method, method_sig, original_visibility,
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
+
arg_types[0][1].raw_type,
|
362
|
+
arg_types[1][1].raw_type,
|
363
|
+
arg_types[2][1].raw_type)
|
364
|
+
when 4
|
361
365
|
create_validator_procedure_fast4(mod, original_method, method_sig, original_visibility,
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
+
arg_types[0][1].raw_type,
|
367
|
+
arg_types[1][1].raw_type,
|
368
|
+
arg_types[2][1].raw_type,
|
369
|
+
arg_types[3][1].raw_type)
|
366
370
|
else
|
367
371
|
raise 'should not happen'
|
368
372
|
end
|
@@ -608,26 +612,28 @@ module T::Private::Methods::CallValidation
|
|
608
612
|
raise 'Should have used create_validator_procedure_medium'
|
609
613
|
end
|
610
614
|
# trampoline to reduce stack frame size
|
611
|
-
|
615
|
+
arg_types = method_sig.arg_types
|
616
|
+
case arg_types.length
|
617
|
+
when 0
|
612
618
|
create_validator_method_medium0(mod, original_method, method_sig, original_visibility, method_sig.return_type)
|
613
|
-
|
619
|
+
when 1
|
614
620
|
create_validator_method_medium1(mod, original_method, method_sig, original_visibility, method_sig.return_type,
|
615
|
-
|
616
|
-
|
621
|
+
arg_types[0][1])
|
622
|
+
when 2
|
617
623
|
create_validator_method_medium2(mod, original_method, method_sig, original_visibility, method_sig.return_type,
|
618
|
-
|
619
|
-
|
620
|
-
|
624
|
+
arg_types[0][1],
|
625
|
+
arg_types[1][1])
|
626
|
+
when 3
|
621
627
|
create_validator_method_medium3(mod, original_method, method_sig, original_visibility, method_sig.return_type,
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
628
|
+
arg_types[0][1],
|
629
|
+
arg_types[1][1],
|
630
|
+
arg_types[2][1])
|
631
|
+
when 4
|
626
632
|
create_validator_method_medium4(mod, original_method, method_sig, original_visibility, method_sig.return_type,
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
633
|
+
arg_types[0][1],
|
634
|
+
arg_types[1][1],
|
635
|
+
arg_types[2][1],
|
636
|
+
arg_types[3][1])
|
631
637
|
else
|
632
638
|
raise 'should not happen'
|
633
639
|
end
|
@@ -940,26 +946,28 @@ module T::Private::Methods::CallValidation
|
|
940
946
|
|
941
947
|
def self.create_validator_procedure_medium(mod, original_method, method_sig, original_visibility)
|
942
948
|
# trampoline to reduce stack frame size
|
943
|
-
|
949
|
+
arg_types = method_sig.arg_types
|
950
|
+
case arg_types.length
|
951
|
+
when 0
|
944
952
|
create_validator_procedure_medium0(mod, original_method, method_sig, original_visibility)
|
945
|
-
|
953
|
+
when 1
|
946
954
|
create_validator_procedure_medium1(mod, original_method, method_sig, original_visibility,
|
947
|
-
|
948
|
-
|
955
|
+
arg_types[0][1])
|
956
|
+
when 2
|
949
957
|
create_validator_procedure_medium2(mod, original_method, method_sig, original_visibility,
|
950
|
-
|
951
|
-
|
952
|
-
|
958
|
+
arg_types[0][1],
|
959
|
+
arg_types[1][1])
|
960
|
+
when 3
|
953
961
|
create_validator_procedure_medium3(mod, original_method, method_sig, original_visibility,
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
962
|
+
arg_types[0][1],
|
963
|
+
arg_types[1][1],
|
964
|
+
arg_types[2][1])
|
965
|
+
when 4
|
958
966
|
create_validator_procedure_medium4(mod, original_method, method_sig, original_visibility,
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
967
|
+
arg_types[0][1],
|
968
|
+
arg_types[1][1],
|
969
|
+
arg_types[2][1],
|
970
|
+
arg_types[3][1])
|
963
971
|
else
|
964
972
|
raise 'should not happen'
|
965
973
|
end
|
@@ -11,26 +11,28 @@ module T::Private::Methods::CallValidation
|
|
11
11
|
raise 'Should have used create_validator_procedure_fast'
|
12
12
|
end
|
13
13
|
# trampoline to reduce stack frame size
|
14
|
-
|
14
|
+
arg_types = method_sig.arg_types
|
15
|
+
case arg_types.length
|
16
|
+
when 0
|
15
17
|
create_validator_method_fast0(mod, original_method, method_sig, original_visibility, method_sig.return_type.raw_type)
|
16
|
-
|
18
|
+
when 1
|
17
19
|
create_validator_method_fast1(mod, original_method, method_sig, original_visibility, method_sig.return_type.raw_type,
|
18
|
-
|
19
|
-
|
20
|
+
arg_types[0][1].raw_type)
|
21
|
+
when 2
|
20
22
|
create_validator_method_fast2(mod, original_method, method_sig, original_visibility, method_sig.return_type.raw_type,
|
21
|
-
|
22
|
-
|
23
|
-
|
23
|
+
arg_types[0][1].raw_type,
|
24
|
+
arg_types[1][1].raw_type)
|
25
|
+
when 3
|
24
26
|
create_validator_method_fast3(mod, original_method, method_sig, original_visibility, method_sig.return_type.raw_type,
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
arg_types[0][1].raw_type,
|
28
|
+
arg_types[1][1].raw_type,
|
29
|
+
arg_types[2][1].raw_type)
|
30
|
+
when 4
|
29
31
|
create_validator_method_fast4(mod, original_method, method_sig, original_visibility, method_sig.return_type.raw_type,
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
32
|
+
arg_types[0][1].raw_type,
|
33
|
+
arg_types[1][1].raw_type,
|
34
|
+
arg_types[2][1].raw_type,
|
35
|
+
arg_types[3][1].raw_type)
|
34
36
|
else
|
35
37
|
raise 'should not happen'
|
36
38
|
end
|
@@ -343,26 +345,28 @@ module T::Private::Methods::CallValidation
|
|
343
345
|
|
344
346
|
def self.create_validator_procedure_fast(mod, original_method, method_sig, original_visibility)
|
345
347
|
# trampoline to reduce stack frame size
|
346
|
-
|
348
|
+
arg_types = method_sig.arg_types
|
349
|
+
case arg_types.length
|
350
|
+
when 0
|
347
351
|
create_validator_procedure_fast0(mod, original_method, method_sig, original_visibility)
|
348
|
-
|
352
|
+
when 1
|
349
353
|
create_validator_procedure_fast1(mod, original_method, method_sig, original_visibility,
|
350
|
-
|
351
|
-
|
354
|
+
arg_types[0][1].raw_type)
|
355
|
+
when 2
|
352
356
|
create_validator_procedure_fast2(mod, original_method, method_sig, original_visibility,
|
353
|
-
|
354
|
-
|
355
|
-
|
357
|
+
arg_types[0][1].raw_type,
|
358
|
+
arg_types[1][1].raw_type)
|
359
|
+
when 3
|
356
360
|
create_validator_procedure_fast3(mod, original_method, method_sig, original_visibility,
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
+
arg_types[0][1].raw_type,
|
362
|
+
arg_types[1][1].raw_type,
|
363
|
+
arg_types[2][1].raw_type)
|
364
|
+
when 4
|
361
365
|
create_validator_procedure_fast4(mod, original_method, method_sig, original_visibility,
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
+
arg_types[0][1].raw_type,
|
367
|
+
arg_types[1][1].raw_type,
|
368
|
+
arg_types[2][1].raw_type,
|
369
|
+
arg_types[3][1].raw_type)
|
366
370
|
else
|
367
371
|
raise 'should not happen'
|
368
372
|
end
|
@@ -608,26 +612,28 @@ module T::Private::Methods::CallValidation
|
|
608
612
|
raise 'Should have used create_validator_procedure_medium'
|
609
613
|
end
|
610
614
|
# trampoline to reduce stack frame size
|
611
|
-
|
615
|
+
arg_types = method_sig.arg_types
|
616
|
+
case arg_types.length
|
617
|
+
when 0
|
612
618
|
create_validator_method_medium0(mod, original_method, method_sig, original_visibility, method_sig.return_type)
|
613
|
-
|
619
|
+
when 1
|
614
620
|
create_validator_method_medium1(mod, original_method, method_sig, original_visibility, method_sig.return_type,
|
615
|
-
|
616
|
-
|
621
|
+
arg_types[0][1])
|
622
|
+
when 2
|
617
623
|
create_validator_method_medium2(mod, original_method, method_sig, original_visibility, method_sig.return_type,
|
618
|
-
|
619
|
-
|
620
|
-
|
624
|
+
arg_types[0][1],
|
625
|
+
arg_types[1][1])
|
626
|
+
when 3
|
621
627
|
create_validator_method_medium3(mod, original_method, method_sig, original_visibility, method_sig.return_type,
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
628
|
+
arg_types[0][1],
|
629
|
+
arg_types[1][1],
|
630
|
+
arg_types[2][1])
|
631
|
+
when 4
|
626
632
|
create_validator_method_medium4(mod, original_method, method_sig, original_visibility, method_sig.return_type,
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
633
|
+
arg_types[0][1],
|
634
|
+
arg_types[1][1],
|
635
|
+
arg_types[2][1],
|
636
|
+
arg_types[3][1])
|
631
637
|
else
|
632
638
|
raise 'should not happen'
|
633
639
|
end
|
@@ -940,26 +946,28 @@ module T::Private::Methods::CallValidation
|
|
940
946
|
|
941
947
|
def self.create_validator_procedure_medium(mod, original_method, method_sig, original_visibility)
|
942
948
|
# trampoline to reduce stack frame size
|
943
|
-
|
949
|
+
arg_types = method_sig.arg_types
|
950
|
+
case arg_types.length
|
951
|
+
when 0
|
944
952
|
create_validator_procedure_medium0(mod, original_method, method_sig, original_visibility)
|
945
|
-
|
953
|
+
when 1
|
946
954
|
create_validator_procedure_medium1(mod, original_method, method_sig, original_visibility,
|
947
|
-
|
948
|
-
|
955
|
+
arg_types[0][1])
|
956
|
+
when 2
|
949
957
|
create_validator_procedure_medium2(mod, original_method, method_sig, original_visibility,
|
950
|
-
|
951
|
-
|
952
|
-
|
958
|
+
arg_types[0][1],
|
959
|
+
arg_types[1][1])
|
960
|
+
when 3
|
953
961
|
create_validator_procedure_medium3(mod, original_method, method_sig, original_visibility,
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
962
|
+
arg_types[0][1],
|
963
|
+
arg_types[1][1],
|
964
|
+
arg_types[2][1])
|
965
|
+
when 4
|
958
966
|
create_validator_procedure_medium4(mod, original_method, method_sig, original_visibility,
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
967
|
+
arg_types[0][1],
|
968
|
+
arg_types[1][1],
|
969
|
+
arg_types[2][1],
|
970
|
+
arg_types[3][1])
|
963
971
|
else
|
964
972
|
raise 'should not happen'
|
965
973
|
end
|
@@ -16,7 +16,6 @@ module T::Private::Methods
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def initialize(mod, raw)
|
19
|
-
# TODO RUBYPLAT-1278 - with ruby 2.5, use kwargs here
|
20
19
|
@decl = Declaration.new(
|
21
20
|
mod,
|
22
21
|
ARG_NOT_PROVIDED, # params
|
@@ -32,15 +31,29 @@ module T::Private::Methods
|
|
32
31
|
)
|
33
32
|
end
|
34
33
|
|
35
|
-
def params(**params)
|
34
|
+
def params(*unused_positional_params, **params)
|
36
35
|
check_live!
|
37
36
|
if !decl.params.equal?(ARG_NOT_PROVIDED)
|
38
37
|
raise BuilderError.new("You can't call .params twice")
|
39
38
|
end
|
40
39
|
|
40
|
+
if unused_positional_params.any?
|
41
|
+
some_or_only = params.any? ? "some" : "only"
|
42
|
+
raise BuilderError.new(<<~MSG)
|
43
|
+
'params' was called with #{some_or_only} positional arguments, but it needs to be called with keyword arguments.
|
44
|
+
The keyword arguments' keys must match the name and order of the method's parameters.
|
45
|
+
MSG
|
46
|
+
end
|
47
|
+
|
41
48
|
if params.empty?
|
42
|
-
raise BuilderError.new(
|
49
|
+
raise BuilderError.new(<<~MSG)
|
50
|
+
'params' was called without any arguments, but it needs to be called with keyword arguments.
|
51
|
+
The keyword arguments' keys must match the name and order of the method's parameters.
|
52
|
+
|
53
|
+
Omit 'params' entirely for methods with no parameters.
|
54
|
+
MSG
|
43
55
|
end
|
56
|
+
|
44
57
|
decl.params = params
|
45
58
|
|
46
59
|
self
|
@@ -66,7 +79,7 @@ module T::Private::Methods
|
|
66
79
|
raise BuilderError.new("You can't call .void after calling .returns.")
|
67
80
|
end
|
68
81
|
|
69
|
-
decl.returns = T::Private::Types::Void
|
82
|
+
decl.returns = T::Private::Types::Void::Private::INSTANCE
|
70
83
|
|
71
84
|
self
|
72
85
|
end
|
@@ -218,15 +231,17 @@ module T::Private::Methods
|
|
218
231
|
decl.on_failure = nil
|
219
232
|
end
|
220
233
|
if decl.params.equal?(ARG_NOT_PROVIDED)
|
221
|
-
decl.params =
|
234
|
+
decl.params = FROZEN_HASH
|
222
235
|
end
|
223
236
|
if decl.type_parameters.equal?(ARG_NOT_PROVIDED)
|
224
|
-
decl.type_parameters =
|
237
|
+
decl.type_parameters = FROZEN_HASH
|
225
238
|
end
|
226
239
|
|
227
240
|
decl.finalized = true
|
228
241
|
|
229
242
|
self
|
230
243
|
end
|
244
|
+
|
245
|
+
FROZEN_HASH = {}.freeze
|
231
246
|
end
|
232
247
|
end
|
@@ -8,17 +8,20 @@ class T::Private::Methods::Signature
|
|
8
8
|
:check_level, :parameters, :on_failure, :override_allow_incompatible,
|
9
9
|
:defined_raw
|
10
10
|
|
11
|
+
UNNAMED_REQUIRED_PARAMETERS = [[:req]].freeze
|
12
|
+
|
11
13
|
def self.new_untyped(method:, mode: T::Private::Methods::Modes.untyped, parameters: method.parameters)
|
12
|
-
# Using `
|
13
|
-
not_typed = T::Private::Types::NotTyped
|
14
|
+
# Using `NotTyped` ensures we'll get an error if we ever try validation on these.
|
15
|
+
not_typed = T::Private::Types::NotTyped::INSTANCE
|
14
16
|
raw_return_type = not_typed
|
15
17
|
# Map missing parameter names to "argN" positionally
|
16
18
|
parameters = parameters.each_with_index.map do |(param_kind, param_name), index|
|
17
19
|
[param_kind, param_name || "arg#{index}"]
|
18
20
|
end
|
19
|
-
raw_arg_types =
|
20
|
-
|
21
|
-
|
21
|
+
raw_arg_types = {}
|
22
|
+
parameters.each do |_, param_name|
|
23
|
+
raw_arg_types[param_name] = not_typed
|
24
|
+
end
|
22
25
|
|
23
26
|
self.new(
|
24
27
|
method: method,
|
@@ -36,8 +39,6 @@ class T::Private::Methods::Signature
|
|
36
39
|
def initialize(method:, method_name:, raw_arg_types:, raw_return_type:, bind:, mode:, check_level:, on_failure:, parameters: method.parameters, override_allow_incompatible: false, defined_raw: false)
|
37
40
|
@method = method
|
38
41
|
@method_name = method_name
|
39
|
-
@arg_types = []
|
40
|
-
@kwarg_types = {}
|
41
42
|
@block_type = nil
|
42
43
|
@block_name = nil
|
43
44
|
@rest_type = nil
|
@@ -48,8 +49,6 @@ class T::Private::Methods::Signature
|
|
48
49
|
@bind = bind ? T::Utils.coerce(bind) : bind
|
49
50
|
@mode = mode
|
50
51
|
@check_level = check_level
|
51
|
-
@req_arg_count = 0
|
52
|
-
@req_kwarg_names = []
|
53
52
|
@has_rest = false
|
54
53
|
@has_keyrest = false
|
55
54
|
@parameters = parameters
|
@@ -57,28 +56,40 @@ class T::Private::Methods::Signature
|
|
57
56
|
@override_allow_incompatible = override_allow_incompatible
|
58
57
|
@defined_raw = defined_raw
|
59
58
|
|
60
|
-
|
59
|
+
# Use T.untyped in lieu of T.nilable to try to avoid unnecessary allocations.
|
60
|
+
arg_types = T.let(nil, T.untyped)
|
61
|
+
kwarg_types = T.let(nil, T.untyped)
|
62
|
+
req_arg_count = 0
|
63
|
+
req_kwarg_names = T.let(nil, T.untyped)
|
64
|
+
|
61
65
|
# If sig params are declared but there is a single parameter with a missing name
|
62
66
|
# **and** the method ends with a "=", assume it is a writer method generated
|
63
67
|
# by attr_writer or attr_accessor
|
64
|
-
writer_method =
|
68
|
+
writer_method = !(raw_arg_types.size == 1 && raw_arg_types.key?(nil)) && parameters == UNNAMED_REQUIRED_PARAMETERS && method_name[-1] == "="
|
65
69
|
# For writer methods, map the single parameter to the method name without the "=" at the end
|
66
70
|
parameters = [[:req, method_name[0...-1].to_sym]] if writer_method
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
+
is_name_missing = parameters.any? {|_, name| !raw_arg_types.key?(name)}
|
72
|
+
if is_name_missing
|
73
|
+
param_names = parameters.map {|_, name| name}
|
74
|
+
missing_names = param_names - raw_arg_types.keys
|
71
75
|
raise "The declaration for `#{method.name}` is missing parameter(s): #{missing_names.join(', ')}"
|
72
|
-
|
73
|
-
|
74
|
-
|
76
|
+
elsif parameters.length == raw_arg_types.size
|
77
|
+
else
|
78
|
+
param_names = parameters.map {|_, name| name}
|
79
|
+
has_extra_names = parameters.count {|_, name| raw_arg_types.key?(name)} < raw_arg_types.size
|
80
|
+
if has_extra_names
|
81
|
+
extra_names = raw_arg_types.keys - param_names
|
82
|
+
raise "The declaration for `#{method.name}` has extra parameter(s): #{extra_names.join(', ')}"
|
83
|
+
end
|
75
84
|
end
|
76
85
|
|
77
86
|
if parameters.size != raw_arg_types.size
|
78
87
|
raise "The declaration for `#{method.name}` has arguments with duplicate names"
|
79
88
|
end
|
89
|
+
i = 0
|
90
|
+
raw_arg_types.each do |type_name, raw_type|
|
91
|
+
param_kind, param_name = parameters[i]
|
80
92
|
|
81
|
-
parameters.zip(raw_arg_types) do |(param_kind, param_name), (type_name, raw_type)|
|
82
93
|
if type_name != param_name
|
83
94
|
hint = ""
|
84
95
|
# Ruby reorders params so that required keyword arguments
|
@@ -92,15 +103,15 @@ class T::Private::Methods::Signature
|
|
92
103
|
end
|
93
104
|
|
94
105
|
raise "Parameter `#{type_name}` is declared out of order (declared as arg number " \
|
95
|
-
"#{
|
96
|
-
"#{
|
106
|
+
"#{i + 1}, defined in the method as arg number " \
|
107
|
+
"#{parameters.index {|_, name| name == type_name} + 1}).#{hint}\nMethod: #{method_desc}"
|
97
108
|
end
|
98
109
|
|
99
110
|
type = T::Utils.coerce(raw_type)
|
100
111
|
|
101
112
|
case param_kind
|
102
113
|
when :req
|
103
|
-
if
|
114
|
+
if (arg_types ? arg_types.length : 0) > req_arg_count
|
104
115
|
# Note that this is actually is supported by Ruby, but it would add complexity to
|
105
116
|
# support it here, and I'm happy to discourage its use anyway.
|
106
117
|
#
|
@@ -111,14 +122,14 @@ class T::Private::Methods::Signature
|
|
111
122
|
# see this error. The simplest resolution is to rename your method.
|
112
123
|
raise "Required params after optional params are not supported in method declarations. Method: #{method_desc}"
|
113
124
|
end
|
114
|
-
|
115
|
-
|
125
|
+
(arg_types ||= []) << [param_name, type]
|
126
|
+
req_arg_count += 1
|
116
127
|
when :opt
|
117
|
-
|
128
|
+
(arg_types ||= []) << [param_name, type]
|
118
129
|
when :key, :keyreq
|
119
|
-
|
130
|
+
(kwarg_types ||= {})[param_name] = type
|
120
131
|
if param_kind == :keyreq
|
121
|
-
|
132
|
+
(req_kwarg_names ||= []) << param_name
|
122
133
|
end
|
123
134
|
when :block
|
124
135
|
@block_name = param_name
|
@@ -134,7 +145,14 @@ class T::Private::Methods::Signature
|
|
134
145
|
else
|
135
146
|
raise "Unexpected param_kind: `#{param_kind}`. Method: #{method_desc}"
|
136
147
|
end
|
148
|
+
|
149
|
+
i += 1
|
137
150
|
end
|
151
|
+
|
152
|
+
@arg_types = arg_types || EMPTY_LIST
|
153
|
+
@kwarg_types = kwarg_types || EMPTY_HASH
|
154
|
+
@req_arg_count = req_arg_count
|
155
|
+
@req_kwarg_names = req_kwarg_names || EMPTY_LIST
|
138
156
|
end
|
139
157
|
|
140
158
|
attr_writer :method_name
|
@@ -179,15 +197,7 @@ class T::Private::Methods::Signature
|
|
179
197
|
kwargs = EMPTY_HASH
|
180
198
|
end
|
181
199
|
|
182
|
-
|
183
|
-
|
184
|
-
if @has_rest
|
185
|
-
rest_count = args_length - @arg_types.length
|
186
|
-
rest_count = 0 if rest_count.negative?
|
187
|
-
|
188
|
-
arg_types += [[@rest_name, @rest_type]] * rest_count
|
189
|
-
|
190
|
-
elsif (args_length < @req_arg_count) || (args_length > @arg_types.length)
|
200
|
+
if !@has_rest && ((args_length < @req_arg_count) || (args_length > @arg_types.length))
|
191
201
|
expected_str = @req_arg_count.to_s
|
192
202
|
if @arg_types.length != @req_arg_count
|
193
203
|
expected_str += "..#{@arg_types.length}"
|
@@ -197,10 +207,23 @@ class T::Private::Methods::Signature
|
|
197
207
|
|
198
208
|
begin
|
199
209
|
it = 0
|
200
|
-
|
201
|
-
|
210
|
+
|
211
|
+
# Process given pre-rest args. When there are no rest args,
|
212
|
+
# this is just the given number of args.
|
213
|
+
while it < args_length && it < @arg_types.length
|
214
|
+
yield @arg_types[it][0], args[it], @arg_types[it][1]
|
202
215
|
it += 1
|
203
216
|
end
|
217
|
+
|
218
|
+
if @has_rest
|
219
|
+
rest_count = args_length - @arg_types.length
|
220
|
+
rest_count = 0 if rest_count.negative?
|
221
|
+
|
222
|
+
rest_count.times do
|
223
|
+
yield @rest_name, args[it], @rest_type
|
224
|
+
it += 1
|
225
|
+
end
|
226
|
+
end
|
204
227
|
end
|
205
228
|
|
206
229
|
kwargs.each do |name, val|
|
@@ -208,6 +231,7 @@ class T::Private::Methods::Signature
|
|
208
231
|
if !type && @has_keyrest
|
209
232
|
type = @keyrest_type
|
210
233
|
end
|
234
|
+
|
211
235
|
yield name, val, type if type
|
212
236
|
end
|
213
237
|
end
|
@@ -221,5 +245,6 @@ class T::Private::Methods::Signature
|
|
221
245
|
"#{@method} at #{loc}"
|
222
246
|
end
|
223
247
|
|
248
|
+
EMPTY_LIST = [].freeze
|
224
249
|
EMPTY_HASH = {}.freeze
|
225
250
|
end
|