steep 0.23.0 → 0.29.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +46 -0
- data/bin/smoke_runner.rb +3 -4
- data/lib/steep.rb +4 -3
- data/lib/steep/annotation_parser.rb +2 -4
- data/lib/steep/ast/builtin.rb +11 -21
- data/lib/steep/ast/types.rb +5 -3
- data/lib/steep/ast/types/any.rb +1 -3
- data/lib/steep/ast/types/boolean.rb +1 -3
- data/lib/steep/ast/types/bot.rb +1 -3
- data/lib/steep/ast/types/class.rb +2 -2
- data/lib/steep/ast/types/factory.rb +249 -89
- data/lib/steep/ast/types/helper.rb +6 -0
- data/lib/steep/ast/types/instance.rb +2 -2
- data/lib/steep/ast/types/intersection.rb +20 -13
- data/lib/steep/ast/types/literal.rb +1 -3
- data/lib/steep/ast/types/logic.rb +63 -0
- data/lib/steep/ast/types/name.rb +15 -67
- data/lib/steep/ast/types/nil.rb +1 -3
- data/lib/steep/ast/types/proc.rb +5 -2
- data/lib/steep/ast/types/record.rb +9 -4
- data/lib/steep/ast/types/self.rb +1 -1
- data/lib/steep/ast/types/top.rb +1 -3
- data/lib/steep/ast/types/tuple.rb +5 -3
- data/lib/steep/ast/types/union.rb +16 -9
- data/lib/steep/ast/types/var.rb +2 -2
- data/lib/steep/ast/types/void.rb +1 -3
- data/lib/steep/drivers/check.rb +4 -0
- data/lib/steep/errors.rb +14 -0
- data/lib/steep/interface/interface.rb +5 -62
- data/lib/steep/interface/method_type.rb +394 -93
- data/lib/steep/interface/substitution.rb +48 -6
- data/lib/steep/module_helper.rb +25 -0
- data/lib/steep/project/completion_provider.rb +48 -51
- data/lib/steep/project/file.rb +3 -3
- data/lib/steep/project/hover_content.rb +4 -6
- data/lib/steep/project/target.rb +5 -2
- data/lib/steep/server/base_worker.rb +5 -3
- data/lib/steep/server/code_worker.rb +2 -0
- data/lib/steep/server/master.rb +10 -1
- data/lib/steep/signature/validator.rb +3 -3
- data/lib/steep/source.rb +4 -3
- data/lib/steep/subtyping/check.rb +46 -59
- data/lib/steep/subtyping/constraints.rb +8 -0
- data/lib/steep/type_construction.rb +771 -513
- data/lib/steep/type_inference/block_params.rb +5 -0
- data/lib/steep/type_inference/constant_env.rb +3 -6
- data/lib/steep/type_inference/context.rb +8 -0
- data/lib/steep/type_inference/context_array.rb +4 -3
- data/lib/steep/type_inference/logic.rb +31 -0
- data/lib/steep/type_inference/logic_type_interpreter.rb +219 -0
- data/lib/steep/type_inference/type_env.rb +2 -2
- data/lib/steep/typing.rb +7 -0
- data/lib/steep/version.rb +1 -1
- data/smoke/alias/a.rb +1 -1
- data/smoke/case/a.rb +1 -1
- data/smoke/hash/d.rb +1 -1
- data/smoke/if/a.rb +1 -1
- data/smoke/module/a.rb +1 -1
- data/smoke/rescue/a.rb +4 -13
- data/smoke/type_case/a.rb +0 -7
- data/steep.gemspec +2 -2
- metadata +10 -10
- data/lib/steep/ast/method_type.rb +0 -126
- data/lib/steep/ast/namespace.rb +0 -80
- data/lib/steep/names.rb +0 -86
@@ -10,8 +10,7 @@ module Steep
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def instance_super_types(type_name, args:)
|
13
|
-
|
14
|
-
ancestors = factory.definition_builder.one_instance_ancestors(type_name_1)
|
13
|
+
ancestors = factory.definition_builder.one_instance_ancestors(type_name)
|
15
14
|
|
16
15
|
subst = unless args.empty?
|
17
16
|
args_ = args.map {|type| factory.type_1(type) }
|
@@ -19,7 +18,7 @@ module Steep
|
|
19
18
|
end
|
20
19
|
|
21
20
|
ancestors.each_ancestor.map do |ancestor|
|
22
|
-
name =
|
21
|
+
name = ancestor.name
|
23
22
|
|
24
23
|
case ancestor
|
25
24
|
when RBS::Definition::Ancestor::Instance
|
@@ -42,9 +41,8 @@ module Steep
|
|
42
41
|
)
|
43
42
|
end
|
44
43
|
when RBS::Definition::Ancestor::Singleton
|
45
|
-
AST::Types::Name::
|
44
|
+
AST::Types::Name::Singleton.new(
|
46
45
|
name: name,
|
47
|
-
constructor: nil,
|
48
46
|
location: nil
|
49
47
|
)
|
50
48
|
end
|
@@ -52,11 +50,10 @@ module Steep
|
|
52
50
|
end
|
53
51
|
|
54
52
|
def singleton_super_types(type_name)
|
55
|
-
|
56
|
-
ancestors = factory.definition_builder.one_singleton_ancestors(type_name_1)
|
53
|
+
ancestors = factory.definition_builder.one_singleton_ancestors(type_name)
|
57
54
|
|
58
55
|
ancestors.each_ancestor.map do |ancestor|
|
59
|
-
name =
|
56
|
+
name = ancestor.name
|
60
57
|
|
61
58
|
case ancestor
|
62
59
|
when RBS::Definition::Ancestor::Instance
|
@@ -78,9 +75,8 @@ module Steep
|
|
78
75
|
)
|
79
76
|
end
|
80
77
|
when RBS::Definition::Ancestor::Singleton
|
81
|
-
AST::Types::Name::
|
78
|
+
AST::Types::Name::Singleton.new(
|
82
79
|
name: name,
|
83
|
-
constructor: nil,
|
84
80
|
location: nil
|
85
81
|
)
|
86
82
|
end
|
@@ -180,6 +176,14 @@ module Steep
|
|
180
176
|
constraints: constraints
|
181
177
|
)
|
182
178
|
|
179
|
+
when relation.super_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.super_type.name)
|
180
|
+
constraints.add(relation.super_type.name, sub_type: relation.sub_type)
|
181
|
+
success(constraints: constraints)
|
182
|
+
|
183
|
+
when relation.sub_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.sub_type.name)
|
184
|
+
constraints.add(relation.sub_type.name, super_type: relation.super_type)
|
185
|
+
success(constraints: constraints)
|
186
|
+
|
183
187
|
when relation.sub_type.is_a?(AST::Types::Union)
|
184
188
|
results = relation.sub_type.types.map do |sub_type|
|
185
189
|
check(Relation.new(sub_type: sub_type, super_type: relation.super_type),
|
@@ -232,14 +236,6 @@ module Steep
|
|
232
236
|
results.find(&:failure?)
|
233
237
|
end
|
234
238
|
|
235
|
-
when relation.super_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.super_type.name)
|
236
|
-
constraints.add(relation.super_type.name, sub_type: relation.sub_type)
|
237
|
-
success(constraints: constraints)
|
238
|
-
|
239
|
-
when relation.sub_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.sub_type.name)
|
240
|
-
constraints.add(relation.sub_type.name, super_type: relation.super_type)
|
241
|
-
success(constraints: constraints)
|
242
|
-
|
243
239
|
when relation.super_type.is_a?(AST::Types::Var) || relation.sub_type.is_a?(AST::Types::Var)
|
244
240
|
failure(error: Result::Failure::UnknownPairError.new(relation: relation),
|
245
241
|
trace: trace)
|
@@ -266,7 +262,7 @@ module Steep
|
|
266
262
|
possible_sub_types = case relation.sub_type
|
267
263
|
when AST::Types::Name::Instance
|
268
264
|
instance_super_types(relation.sub_type.name, args: relation.sub_type.args)
|
269
|
-
when AST::Types::Name::
|
265
|
+
when AST::Types::Name::Singleton
|
270
266
|
singleton_super_types(relation.sub_type.name)
|
271
267
|
else
|
272
268
|
[]
|
@@ -302,10 +298,9 @@ module Steep
|
|
302
298
|
when relation.sub_type.is_a?(AST::Types::Tuple) && relation.super_type.is_a?(AST::Types::Tuple)
|
303
299
|
if relation.sub_type.types.size >= relation.super_type.types.size
|
304
300
|
pairs = relation.sub_type.types.take(relation.super_type.types.size).zip(relation.super_type.types)
|
305
|
-
results = pairs.
|
301
|
+
results = pairs.map do |t1, t2|
|
306
302
|
relation = Relation.new(sub_type: t1, super_type: t2)
|
307
|
-
|
308
|
-
check(relation.flip, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)]
|
303
|
+
check(relation, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)
|
309
304
|
end
|
310
305
|
|
311
306
|
if results.all?(&:success?)
|
@@ -318,16 +313,17 @@ module Steep
|
|
318
313
|
trace: trace)
|
319
314
|
end
|
320
315
|
|
321
|
-
when relation.sub_type.is_a?(AST::Types::Tuple) && relation.super_type
|
322
|
-
|
323
|
-
|
316
|
+
when relation.sub_type.is_a?(AST::Types::Tuple) && AST::Builtin::Array.instance_type?(relation.super_type)
|
317
|
+
tuple_element_type = AST::Types::Union.build(
|
318
|
+
types: relation.sub_type.types,
|
319
|
+
location: relation.sub_type.location
|
320
|
+
)
|
324
321
|
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
constraints: constraints)
|
322
|
+
check(Relation.new(sub_type: tuple_element_type, super_type: relation.super_type.args[0]),
|
323
|
+
self_type: self_type,
|
324
|
+
assumption: assumption,
|
325
|
+
trace: trace,
|
326
|
+
constraints: constraints)
|
331
327
|
|
332
328
|
when relation.sub_type.is_a?(AST::Types::Record) && relation.super_type.is_a?(AST::Types::Record)
|
333
329
|
if Set.new(relation.sub_type.elements.keys).superset?(Set.new(relation.super_type.elements.keys))
|
@@ -394,12 +390,12 @@ module Steep
|
|
394
390
|
end
|
395
391
|
|
396
392
|
def definition_for_type(type)
|
397
|
-
type_name =
|
393
|
+
type_name = type.name
|
398
394
|
|
399
395
|
case type
|
400
396
|
when AST::Types::Name::Instance
|
401
397
|
factory.definition_builder.build_instance(type_name)
|
402
|
-
when AST::Types::Name::
|
398
|
+
when AST::Types::Name::Singleton
|
403
399
|
factory.definition_builder.build_singleton(type_name)
|
404
400
|
when AST::Types::Name::Interface
|
405
401
|
factory.definition_builder.build_interface(type_name)
|
@@ -484,11 +480,7 @@ module Steep
|
|
484
480
|
if sub_type.name == super_type.name && sub_type.args.size == super_type.args.size
|
485
481
|
sub_type.args.zip(super_type.args)
|
486
482
|
end
|
487
|
-
when sub_type.is_a?(AST::Types::Name::
|
488
|
-
if sub_type.name == super_type.name
|
489
|
-
[]
|
490
|
-
end
|
491
|
-
when sub_type.is_a?(AST::Types::Name::Module) && super_type.is_a?(AST::Types::Name::Module)
|
483
|
+
when sub_type.is_a?(AST::Types::Name::Singleton) && super_type.is_a?(AST::Types::Name::Singleton)
|
492
484
|
if sub_type.name == super_type.name
|
493
485
|
[]
|
494
486
|
end
|
@@ -535,29 +527,24 @@ module Steep
|
|
535
527
|
|
536
528
|
def check_method(name, sub_method, super_method, self_type:, assumption:, trace:, constraints:)
|
537
529
|
trace.method name, sub_method, super_method do
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
trace: trace,
|
548
|
-
constraints: constraints
|
549
|
-
end.yield_self do |results|
|
550
|
-
results.find(&:success?) || results[0]
|
551
|
-
end
|
530
|
+
super_method.method_types.map do |super_type|
|
531
|
+
sub_method.method_types.map do |sub_type|
|
532
|
+
check_generic_method_type name,
|
533
|
+
sub_type,
|
534
|
+
super_type,
|
535
|
+
self_type: self_type,
|
536
|
+
assumption: assumption,
|
537
|
+
trace: trace,
|
538
|
+
constraints: constraints
|
552
539
|
end.yield_self do |results|
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
540
|
+
results.find(&:success?) || results[0]
|
541
|
+
end
|
542
|
+
end.yield_self do |results|
|
543
|
+
if results.all?(&:success?)
|
544
|
+
success constraints: constraints
|
545
|
+
else
|
546
|
+
results.select(&:failure?).last
|
558
547
|
end
|
559
|
-
else
|
560
|
-
raise "aaaaaaaaaaaaaa"
|
561
548
|
end
|
562
549
|
end
|
563
550
|
end
|
@@ -104,6 +104,14 @@ module Steep
|
|
104
104
|
def add(var, sub_type: nil, super_type: nil)
|
105
105
|
subs, supers = dictionary[var]
|
106
106
|
|
107
|
+
if sub_type.is_a?(AST::Types::Logic::Base)
|
108
|
+
sub_type = AST::Builtin.bool_type
|
109
|
+
end
|
110
|
+
|
111
|
+
if super_type.is_a?(AST::Types::Logic::Base)
|
112
|
+
super_type = AST::Builtin.bool_type
|
113
|
+
end
|
114
|
+
|
107
115
|
if super_type && !super_type.is_a?(AST::Types::Top)
|
108
116
|
supers << eliminate_variable(super_type, to: AST::Types::Top.new)
|
109
117
|
end
|
@@ -33,6 +33,8 @@ module Steep
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
include ModuleHelper
|
37
|
+
|
36
38
|
attr_reader :checker
|
37
39
|
attr_reader :source
|
38
40
|
attr_reader :annotations
|
@@ -113,6 +115,7 @@ module Steep
|
|
113
115
|
end
|
114
116
|
|
115
117
|
def check_relation(sub_type:, super_type:, constraints: Subtyping::Constraints.empty)
|
118
|
+
Steep.logger.debug { "check_relation: self:#{self_type} |- #{sub_type} <: #{super_type}" }
|
116
119
|
checker.check(Subtyping::Relation.new(sub_type: sub_type, super_type: super_type), self_type: self_type, constraints: constraints)
|
117
120
|
end
|
118
121
|
|
@@ -168,7 +171,7 @@ module Steep
|
|
168
171
|
|
169
172
|
super_method = if definition
|
170
173
|
if (this_method = definition.methods[method_name])
|
171
|
-
if module_context&.class_name ==
|
174
|
+
if module_context&.class_name == this_method.defined_in
|
172
175
|
this_method.super_method
|
173
176
|
else
|
174
177
|
this_method
|
@@ -253,7 +256,7 @@ module Steep
|
|
253
256
|
end
|
254
257
|
|
255
258
|
if name
|
256
|
-
absolute_name_ =
|
259
|
+
absolute_name_ = name
|
257
260
|
entry = checker.factory.env.class_decls[absolute_name_]
|
258
261
|
AST::Annotation::Implements::Module.new(
|
259
262
|
name: name,
|
@@ -264,7 +267,7 @@ module Steep
|
|
264
267
|
end
|
265
268
|
|
266
269
|
def for_module(node)
|
267
|
-
new_module_name =
|
270
|
+
new_module_name = module_name_from_node(node.children.first) or raise "Unexpected module name: #{node.children.first}"
|
268
271
|
new_namespace = nested_namespace_for_module(new_module_name)
|
269
272
|
|
270
273
|
const_context = [new_namespace] + self.module_context.const_env.context
|
@@ -279,14 +282,13 @@ module Steep
|
|
279
282
|
module_name = implement_module_name.name
|
280
283
|
module_args = implement_module_name.args.map {|x| AST::Types::Var.new(name: x)}
|
281
284
|
|
282
|
-
type_name_ =
|
285
|
+
type_name_ = implement_module_name.name
|
283
286
|
module_entry = checker.factory.definition_builder.env.class_decls[type_name_]
|
284
287
|
instance_def = checker.factory.definition_builder.build_instance(type_name_)
|
285
288
|
module_def = checker.factory.definition_builder.build_singleton(type_name_)
|
286
289
|
|
287
290
|
instance_type = AST::Types::Intersection.build(
|
288
291
|
types: [
|
289
|
-
AST::Types::Name::Instance.new(name: module_name, args: module_args),
|
290
292
|
AST::Builtin::Object.instance_type,
|
291
293
|
*module_entry.self_types.map {|module_self|
|
292
294
|
type = case
|
@@ -304,11 +306,12 @@ module Steep
|
|
304
306
|
)
|
305
307
|
end
|
306
308
|
checker.factory.type(type)
|
307
|
-
}
|
309
|
+
},
|
310
|
+
AST::Types::Name::Instance.new(name: module_name, args: module_args)
|
308
311
|
].compact
|
309
312
|
)
|
310
313
|
|
311
|
-
module_type = AST::Types::Name::
|
314
|
+
module_type = AST::Types::Name::Singleton.new(name: module_name)
|
312
315
|
end
|
313
316
|
|
314
317
|
if annots.instance_type
|
@@ -358,8 +361,8 @@ module Steep
|
|
358
361
|
end
|
359
362
|
|
360
363
|
def for_class(node)
|
361
|
-
new_class_name =
|
362
|
-
super_class_name = node.children[1] &&
|
364
|
+
new_class_name = module_name_from_node(node.children.first) or raise "Unexpected class name: #{node.children.first}"
|
365
|
+
super_class_name = node.children[1] && module_name_from_node(node.children[1])
|
363
366
|
new_namespace = nested_namespace_for_module(new_class_name)
|
364
367
|
|
365
368
|
annots = source.annotations(block: node, factory: checker.factory, current_module: new_namespace)
|
@@ -374,12 +377,12 @@ module Steep
|
|
374
377
|
class_name = implement_module_name.name
|
375
378
|
class_args = implement_module_name.args.map {|x| AST::Types::Var.new(name: x)}
|
376
379
|
|
377
|
-
type_name_ =
|
380
|
+
type_name_ = implement_module_name.name
|
378
381
|
instance_def = checker.factory.definition_builder.build_instance(type_name_)
|
379
382
|
module_def = checker.factory.definition_builder.build_singleton(type_name_)
|
380
383
|
|
381
384
|
instance_type = AST::Types::Name::Instance.new(name: class_name, args: class_args)
|
382
|
-
module_type = AST::Types::Name::
|
385
|
+
module_type = AST::Types::Name::Singleton.new(name: class_name)
|
383
386
|
end
|
384
387
|
|
385
388
|
if annots.instance_type
|
@@ -443,28 +446,36 @@ module Steep
|
|
443
446
|
end
|
444
447
|
|
445
448
|
module_type = case instance_type
|
446
|
-
when AST::Types::Name::
|
447
|
-
|
448
|
-
|
449
|
-
|
449
|
+
when AST::Types::Name::Singleton
|
450
|
+
type_name = instance_type.name
|
451
|
+
|
452
|
+
case checker.factory.env.class_decls[type_name]
|
453
|
+
when RBS::Environment::ModuleEntry
|
454
|
+
AST::Builtin::Module.instance_type
|
455
|
+
when RBS::Environment::ClassEntry
|
456
|
+
AST::Builtin::Class.instance_type
|
457
|
+
else
|
458
|
+
raise
|
459
|
+
end
|
460
|
+
|
450
461
|
when AST::Types::Name::Instance
|
451
|
-
instance_type.
|
462
|
+
instance_type.to_module
|
452
463
|
else
|
453
|
-
|
464
|
+
return
|
454
465
|
end
|
455
466
|
|
456
467
|
instance_definition = case instance_type
|
457
|
-
when AST::Types::Name::
|
458
|
-
type_name =
|
468
|
+
when AST::Types::Name::Singleton
|
469
|
+
type_name = instance_type.name
|
459
470
|
checker.factory.definition_builder.build_singleton(type_name)
|
460
471
|
when AST::Types::Name::Instance
|
461
|
-
type_name =
|
472
|
+
type_name = instance_type.name
|
462
473
|
checker.factory.definition_builder.build_instance(type_name)
|
463
474
|
end
|
464
475
|
|
465
476
|
module_definition = case module_type
|
466
|
-
when AST::Types::Name::
|
467
|
-
type_name =
|
477
|
+
when AST::Types::Name::Singleton
|
478
|
+
type_name = instance_type.name
|
468
479
|
checker.factory.definition_builder.build_singleton(type_name)
|
469
480
|
else
|
470
481
|
nil
|
@@ -638,7 +649,10 @@ module Steep
|
|
638
649
|
when :__skip__
|
639
650
|
add_typing(node, type: AST::Builtin.any_type)
|
640
651
|
else
|
641
|
-
hint
|
652
|
+
if !hint || hint.is_a?(AST::Types::Void)
|
653
|
+
hint = context.lvar_env.declared_types[name]&.type
|
654
|
+
end
|
655
|
+
|
642
656
|
rhs_result = synthesize(rhs, hint: hint)
|
643
657
|
|
644
658
|
constr = rhs_result.constr.update_lvar_env do |lvar_env|
|
@@ -683,8 +697,8 @@ module Steep
|
|
683
697
|
yield_self do
|
684
698
|
if self_class?(node)
|
685
699
|
module_type = expand_alias(module_context.module_type)
|
686
|
-
type = if module_type.is_a?(AST::Types::Name::
|
687
|
-
AST::Types::Name::
|
700
|
+
type = if module_type.is_a?(AST::Types::Name::Singleton)
|
701
|
+
AST::Types::Name::Singleton.new(name: module_type.name)
|
688
702
|
else
|
689
703
|
module_type
|
690
704
|
end
|
@@ -699,8 +713,8 @@ module Steep
|
|
699
713
|
yield_self do
|
700
714
|
pair = if self_class?(node)
|
701
715
|
module_type = expand_alias(module_context.module_type)
|
702
|
-
type = if module_type.is_a?(AST::Types::Name::
|
703
|
-
AST::Types::Name::
|
716
|
+
type = if module_type.is_a?(AST::Types::Name::Singleton)
|
717
|
+
AST::Types::Name::Singleton.new(name: module_type.name)
|
704
718
|
else
|
705
719
|
module_type
|
706
720
|
end
|
@@ -744,6 +758,23 @@ module Steep
|
|
744
758
|
|
745
759
|
constr.add_typing(node, type: type)
|
746
760
|
|
761
|
+
when :cvasgn
|
762
|
+
var_node = lhs.updated(:cvar)
|
763
|
+
send_node = rhs.updated(:send, [var_node, op, rhs])
|
764
|
+
new_node = node.updated(:cvasgn, [lhs.children[0], send_node])
|
765
|
+
|
766
|
+
type, constr = synthesize(new_node, hint: hint)
|
767
|
+
|
768
|
+
constr.add_typing(node, type: type)
|
769
|
+
|
770
|
+
when :send
|
771
|
+
new_rhs = rhs.updated(:send, [lhs, node.children[1], node.children[2]])
|
772
|
+
new_node = lhs.updated(:send, [lhs.children[0], :"#{lhs.children[1]}=", *lhs.children.drop(2), new_rhs])
|
773
|
+
|
774
|
+
type, constr = synthesize(new_node, hint: hint)
|
775
|
+
|
776
|
+
constr.add_typing(node, type: type)
|
777
|
+
|
747
778
|
else
|
748
779
|
Steep.logger.error("Unexpected op_asgn lhs: #{lhs.type}")
|
749
780
|
|
@@ -760,11 +791,10 @@ module Steep
|
|
760
791
|
synthesize(child)
|
761
792
|
end
|
762
793
|
|
763
|
-
super_method = Interface::Interface::
|
764
|
-
method_context.super_method.method_types.map {|method_type|
|
794
|
+
super_method = Interface::Interface::Entry.new(
|
795
|
+
method_types: method_context.super_method.method_types.map {|method_type|
|
765
796
|
checker.factory.method_type(method_type, self_type: self_type)
|
766
|
-
}
|
767
|
-
incompatible: false
|
797
|
+
}
|
768
798
|
)
|
769
799
|
args = TypeInference::SendArgs.from_nodes(node.children.dup)
|
770
800
|
|
@@ -811,7 +841,7 @@ module Steep
|
|
811
841
|
new.typing.add_context_for_body(node, context: new.context)
|
812
842
|
|
813
843
|
each_child_node(args_node) do |arg|
|
814
|
-
new.synthesize(arg)
|
844
|
+
_, new = new.synthesize(arg)
|
815
845
|
end
|
816
846
|
|
817
847
|
body_pair = if body_node
|
@@ -860,10 +890,10 @@ module Steep
|
|
860
890
|
self_type = expand_self(self_type)
|
861
891
|
definition = case self_type
|
862
892
|
when AST::Types::Name::Instance
|
863
|
-
name =
|
893
|
+
name = self_type.name
|
864
894
|
checker.factory.definition_builder.build_singleton(name)
|
865
|
-
when AST::Types::Name::
|
866
|
-
name =
|
895
|
+
when AST::Types::Name::Singleton
|
896
|
+
name = self_type.name
|
867
897
|
checker.factory.definition_builder.build_singleton(name)
|
868
898
|
end
|
869
899
|
|
@@ -999,11 +1029,17 @@ module Steep
|
|
999
1029
|
yield_self do
|
1000
1030
|
var = node.children[0]
|
1001
1031
|
type = context.lvar_env[var.name]
|
1002
|
-
|
1032
|
+
|
1033
|
+
if type
|
1034
|
+
add_typing(node, type: type)
|
1035
|
+
else
|
1003
1036
|
type = AST::Builtin.any_type
|
1004
|
-
|
1037
|
+
if context&.method_context&.method_type
|
1038
|
+
Steep.logger.error { "Unknown arg type: #{node}" }
|
1039
|
+
end
|
1040
|
+
|
1041
|
+
lvasgn(node, type)
|
1005
1042
|
end
|
1006
|
-
add_typing(node, type: type)
|
1007
1043
|
end
|
1008
1044
|
|
1009
1045
|
when :optarg, :kwoptarg
|
@@ -1011,12 +1047,13 @@ module Steep
|
|
1011
1047
|
var = node.children[0]
|
1012
1048
|
rhs = node.children[1]
|
1013
1049
|
|
1014
|
-
|
1050
|
+
var_type = context.lvar_env[var.name]
|
1051
|
+
node_type, constr = synthesize(rhs, hint: var_type)
|
1015
1052
|
|
1016
|
-
|
1053
|
+
type = AST::Types::Union.build(types: [var_type, node_type])
|
1017
1054
|
|
1018
1055
|
constr_ = constr.update_lvar_env do |env|
|
1019
|
-
env.assign(var.name, node: node, type:
|
1056
|
+
env.assign(var.name, node: node, type: type) do |declared_type, type, result|
|
1020
1057
|
typing.add_error(
|
1021
1058
|
Errors::IncompatibleAssignment.new(node: node,
|
1022
1059
|
lhs_type: declared_type,
|
@@ -1026,7 +1063,7 @@ module Steep
|
|
1026
1063
|
end
|
1027
1064
|
end
|
1028
1065
|
|
1029
|
-
add_typing(node, type:
|
1066
|
+
add_typing(node, type: type, constr: constr_)
|
1030
1067
|
end
|
1031
1068
|
|
1032
1069
|
when :restarg
|
@@ -1034,7 +1071,9 @@ module Steep
|
|
1034
1071
|
var = node.children[0]
|
1035
1072
|
type = context.lvar_env[var.name]
|
1036
1073
|
unless type
|
1037
|
-
|
1074
|
+
if context&.method_context&.method_type
|
1075
|
+
Steep.logger.error { "Unknown variable: #{node}" }
|
1076
|
+
end
|
1038
1077
|
typing.add_error Errors::FallbackAny.new(node: node)
|
1039
1078
|
type = AST::Builtin::Array.instance_type(AST::Builtin.any_type)
|
1040
1079
|
end
|
@@ -1047,7 +1086,9 @@ module Steep
|
|
1047
1086
|
var = node.children[0]
|
1048
1087
|
type = context.lvar_env[var.name]
|
1049
1088
|
unless type
|
1050
|
-
|
1089
|
+
if context&.method_context&.method_type
|
1090
|
+
Steep.logger.error { "Unknown variable: #{node}" }
|
1091
|
+
end
|
1051
1092
|
typing.add_error Errors::FallbackAny.new(node: node)
|
1052
1093
|
type = AST::Builtin::Hash.instance_type(AST::Builtin::Symbol.instance_type, AST::Builtin.any_type)
|
1053
1094
|
end
|
@@ -1202,6 +1243,17 @@ module Steep
|
|
1202
1243
|
type, constr = synthesize(node.children[0])
|
1203
1244
|
constructor = constr.for_sclass(node, type)
|
1204
1245
|
|
1246
|
+
unless constructor
|
1247
|
+
typing.add_error(
|
1248
|
+
Errors::UnsupportedSyntax.new(
|
1249
|
+
node: node,
|
1250
|
+
message: "sclass receiver must be instance type or singleton type, but type given `#{type}`"
|
1251
|
+
)
|
1252
|
+
)
|
1253
|
+
constr.add_typing(node, type: AST::Builtin.nil_type)
|
1254
|
+
return
|
1255
|
+
end
|
1256
|
+
|
1205
1257
|
constructor.typing.add_context_for_node(node, context: constructor.context)
|
1206
1258
|
constructor.typing.add_context_for_body(node, context: constructor.context)
|
1207
1259
|
|
@@ -1213,14 +1265,14 @@ module Steep
|
|
1213
1265
|
end
|
1214
1266
|
end
|
1215
1267
|
|
1216
|
-
add_typing(node, type: AST::Builtin.nil_type)
|
1268
|
+
constr.add_typing(node, type: AST::Builtin.nil_type)
|
1217
1269
|
end
|
1218
1270
|
|
1219
1271
|
when :self
|
1220
1272
|
add_typing node, type: AST::Types::Self.new
|
1221
1273
|
|
1222
1274
|
when :const
|
1223
|
-
const_name =
|
1275
|
+
const_name = module_name_from_node(node)
|
1224
1276
|
|
1225
1277
|
if const_name
|
1226
1278
|
type = type_env.get(const: const_name) do
|
@@ -1233,7 +1285,7 @@ module Steep
|
|
1233
1285
|
|
1234
1286
|
when :casgn
|
1235
1287
|
yield_self do
|
1236
|
-
const_name =
|
1288
|
+
const_name = module_name_from_node(node)
|
1237
1289
|
if const_name
|
1238
1290
|
const_type = type_env.get(const: const_name) {}
|
1239
1291
|
value_type = synthesize(node.children.last, hint: const_type).type
|
@@ -1301,84 +1353,62 @@ module Steep
|
|
1301
1353
|
when :array
|
1302
1354
|
yield_self do
|
1303
1355
|
if node.children.empty?
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1310
|
-
end
|
1311
|
-
end
|
1312
|
-
|
1313
|
-
add_typing(node, type: array_type || AST::Builtin::Array.instance_type(AST::Builtin.any_type))
|
1314
|
-
else
|
1315
|
-
is_tuple = nil
|
1316
|
-
|
1317
|
-
expand_alias(hint) do |hint|
|
1318
|
-
is_tuple = hint.is_a?(AST::Types::Tuple)
|
1319
|
-
is_tuple &&= node.children.all? {|child| child.type != :splat}
|
1320
|
-
is_tuple &&= node.children.size >= hint.types.size
|
1321
|
-
is_tuple &&= hint.types.map.with_index do |child_type, index|
|
1322
|
-
child_node = node.children[index]
|
1323
|
-
[synthesize(child_node, hint: child_type).type, child_type]
|
1324
|
-
end.all? do |node_type, hint_type|
|
1325
|
-
result = check_relation(sub_type: node_type, super_type: hint_type)
|
1326
|
-
result.success?
|
1356
|
+
if hint
|
1357
|
+
array = AST::Builtin::Array.instance_type(AST::Builtin.any_type)
|
1358
|
+
if check_relation(sub_type: array, super_type: hint).success?
|
1359
|
+
add_typing node, type: hint
|
1360
|
+
else
|
1361
|
+
add_typing node, type: array
|
1327
1362
|
end
|
1328
|
-
end
|
1329
|
-
|
1330
|
-
if is_tuple
|
1331
|
-
array_type = hint
|
1332
1363
|
else
|
1333
|
-
|
1334
|
-
|
1364
|
+
typing.add_error Errors::FallbackAny.new(node: node)
|
1365
|
+
add_typing node, type: AST::Builtin::Array.instance_type(AST::Builtin.any_type)
|
1366
|
+
end
|
1367
|
+
else
|
1368
|
+
node_range = node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
|
1369
|
+
|
1370
|
+
if hint && !(tuples = select_flatten_types(hint) {|type| type.is_a?(AST::Types::Tuple) }).empty?
|
1371
|
+
tuples.each do |tuple|
|
1372
|
+
typing.new_child(node_range) do |child_typing|
|
1373
|
+
pair = with_new_typing(child_typing).try_tuple_type(node, tuple)
|
1374
|
+
if pair && pair.constr.check_relation(sub_type: pair.type, super_type: hint).success?
|
1375
|
+
child_typing.save!
|
1376
|
+
return pair.with(constr: pair.constr.with_new_typing(typing))
|
1377
|
+
end
|
1378
|
+
end
|
1335
1379
|
end
|
1380
|
+
end
|
1336
1381
|
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
ty.types
|
1345
|
-
else
|
1346
|
-
[ty]
|
1347
|
-
end
|
1348
|
-
end
|
1349
|
-
end.map do |type|
|
1350
|
-
case
|
1351
|
-
when AST::Builtin::Array.instance_type?(type)
|
1352
|
-
type.args.first
|
1353
|
-
when AST::Builtin::Range.instance_type?(type)
|
1354
|
-
type.args.first
|
1355
|
-
else
|
1356
|
-
type
|
1357
|
-
end
|
1382
|
+
if hint && !(arrays = select_flatten_types(hint) {|type| AST::Builtin::Array.instance_type?(type) }).empty?
|
1383
|
+
arrays.each do |array|
|
1384
|
+
typing.new_child(node_range) do |child_typing|
|
1385
|
+
pair = with_new_typing(child_typing).try_array_type(node, array)
|
1386
|
+
if pair.constr.check_relation(sub_type: pair.type, super_type: hint).success?
|
1387
|
+
child_typing.save!
|
1388
|
+
return pair.with(constr: pair.constr.with_new_typing(typing))
|
1358
1389
|
end
|
1359
|
-
else
|
1360
|
-
[select_super_type(synthesize(e, hint: element_hint).type, element_hint)]
|
1361
1390
|
end
|
1362
1391
|
end
|
1363
|
-
array_type = AST::Builtin::Array.instance_type(AST::Types::Union.build(types: element_types))
|
1364
1392
|
end
|
1365
1393
|
|
1366
|
-
|
1394
|
+
try_array_type(node, nil)
|
1367
1395
|
end
|
1368
1396
|
end
|
1369
1397
|
|
1370
1398
|
when :and
|
1371
1399
|
yield_self do
|
1372
1400
|
left, right = node.children
|
1373
|
-
logic = TypeInference::Logic.new(subtyping: checker)
|
1374
|
-
truthy, falsey = logic.nodes(node: left)
|
1375
1401
|
|
1376
1402
|
left_type, constr = synthesize(left)
|
1377
|
-
truthy_env, falsey_env = logic.environments(truthy_vars: truthy.vars,
|
1378
|
-
falsey_vars: falsey.vars,
|
1379
|
-
lvar_env: constr.context.lvar_env)
|
1380
1403
|
|
1381
|
-
|
1404
|
+
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
|
1405
|
+
truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: left_type, node: left)
|
1406
|
+
|
1407
|
+
right_type, constr = constr
|
1408
|
+
.update_lvar_env { truthy_env }
|
1409
|
+
.tap {|constr| typing.add_context_for_node(right, context: constr.context) }
|
1410
|
+
.for_branch(right)
|
1411
|
+
.synthesize(right)
|
1382
1412
|
|
1383
1413
|
type = if left_type.is_a?(AST::Types::Boolean)
|
1384
1414
|
union_type(left_type, right_type)
|
@@ -1400,16 +1430,18 @@ module Steep
|
|
1400
1430
|
when :or
|
1401
1431
|
yield_self do
|
1402
1432
|
left, right = node.children
|
1403
|
-
logic = TypeInference::Logic.new(subtyping: checker)
|
1404
|
-
truthy, falsey = logic.nodes(node: left)
|
1405
1433
|
|
1406
1434
|
left_type, constr = synthesize(left, hint: hint)
|
1407
|
-
truthy_env, falsey_env = logic.environments(truthy_vars: truthy.vars,
|
1408
|
-
falsey_vars: falsey.vars,
|
1409
|
-
lvar_env: constr.context.lvar_env)
|
1410
|
-
left_type_t, _ = logic.partition_union(left_type)
|
1411
1435
|
|
1412
|
-
|
1436
|
+
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
|
1437
|
+
truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: left_type, node: left)
|
1438
|
+
|
1439
|
+
left_type_t, _ = checker.factory.unwrap_optional(left_type)
|
1440
|
+
right_type, constr = constr
|
1441
|
+
.update_lvar_env { falsey_env }
|
1442
|
+
.tap {|constr| typing.add_context_for_node(right, context: constr.context) }
|
1443
|
+
.for_branch(right)
|
1444
|
+
.synthesize(right, hint: left_type_t)
|
1413
1445
|
|
1414
1446
|
type = union_type(left_type_t, right_type)
|
1415
1447
|
|
@@ -1428,12 +1460,8 @@ module Steep
|
|
1428
1460
|
cond, true_clause, false_clause = node.children
|
1429
1461
|
|
1430
1462
|
cond_type, constr = synthesize(cond)
|
1431
|
-
|
1432
|
-
|
1433
|
-
truthys, falseys = logic.nodes(node: cond)
|
1434
|
-
truthy_env, falsey_env = logic.environments(truthy_vars: truthys.vars,
|
1435
|
-
falsey_vars: falseys.vars,
|
1436
|
-
lvar_env: constr.context.lvar_env)
|
1463
|
+
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: constr.typing)
|
1464
|
+
truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: cond_type, node: cond)
|
1437
1465
|
|
1438
1466
|
if true_clause
|
1439
1467
|
true_pair = constr
|
@@ -1483,90 +1511,109 @@ module Steep
|
|
1483
1511
|
cond, *whens, els = node.children
|
1484
1512
|
|
1485
1513
|
constr = self
|
1514
|
+
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
|
1486
1515
|
|
1487
1516
|
if cond
|
1488
|
-
|
1489
|
-
cond_type = expand_alias(cond_type)
|
1490
|
-
if cond_type.is_a?(AST::Types::Union)
|
1491
|
-
var_names = TypeConstruction.value_variables(cond)
|
1492
|
-
var_types = cond_type.types.dup
|
1493
|
-
end
|
1494
|
-
end
|
1517
|
+
branch_pairs = []
|
1495
1518
|
|
1496
|
-
|
1519
|
+
cond_type, constr = constr.synthesize(cond)
|
1520
|
+
_, cond_vars = interpreter.decompose_value(cond)
|
1497
1521
|
|
1498
|
-
|
1499
|
-
|
1522
|
+
when_constr = constr
|
1523
|
+
whens.each do |clause|
|
1524
|
+
*tests, body = clause.children
|
1500
1525
|
|
1501
|
-
|
1502
|
-
|
1526
|
+
test_constr = when_constr
|
1527
|
+
test_envs = []
|
1503
1528
|
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1529
|
+
tests.each do |test|
|
1530
|
+
test_node = test.updated(:send, [test, :===, cond.dup])
|
1531
|
+
test_type, test_constr = test_constr.synthesize(test_node)
|
1532
|
+
truthy_env, falsy_env = interpreter.eval(type: test_type, node: test_node, env: test_constr.context.lvar_env)
|
1533
|
+
test_envs << truthy_env
|
1534
|
+
test_constr = test_constr.update_lvar_env { falsy_env }
|
1535
|
+
end
|
1536
|
+
|
1537
|
+
body_constr = when_constr.update_lvar_env {|env| env.except(cond_vars).join(*test_envs) }
|
1538
|
+
|
1539
|
+
if body
|
1540
|
+
branch_pairs << body_constr
|
1541
|
+
.for_branch(body)
|
1542
|
+
.tap {|constr| typing.add_context_for_node(body, context: constr.context) }
|
1543
|
+
.synthesize(body, hint: hint)
|
1544
|
+
else
|
1545
|
+
branch_pairs << Pair.new(type: AST::Builtin.nil_type, constr: body_constr)
|
1546
|
+
end
|
1547
|
+
|
1548
|
+
when_constr = test_constr
|
1507
1549
|
end
|
1508
1550
|
|
1509
|
-
if
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
var_type.is_a?(AST::Types::Name::Base) && var_type.name == test_type.name
|
1514
|
-
end
|
1515
|
-
if filtered_types.empty?
|
1516
|
-
to_instance_type(test_type)
|
1517
|
-
else
|
1518
|
-
filtered_types
|
1519
|
-
end
|
1520
|
-
end
|
1551
|
+
if els
|
1552
|
+
begin_pos = node.loc.else.end_pos
|
1553
|
+
end_pos = node.loc.end.begin_pos
|
1554
|
+
typing.add_context(begin_pos..end_pos, context: when_constr.context)
|
1521
1555
|
|
1522
|
-
|
1523
|
-
|
1524
|
-
type.is_a?(AST::Types::Name::Base) && test_type.name == type.name
|
1525
|
-
end
|
1526
|
-
end
|
1556
|
+
branch_pairs << when_constr.synthesize(els, hint: hint)
|
1557
|
+
end
|
1527
1558
|
|
1528
|
-
|
1529
|
-
|
1530
|
-
hash[var_name] = var_type_in_body
|
1531
|
-
end
|
1559
|
+
types = branch_pairs.map(&:type)
|
1560
|
+
constrs = branch_pairs.map(&:constr)
|
1532
1561
|
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1562
|
+
unless els
|
1563
|
+
constrs << when_constr
|
1564
|
+
end
|
1565
|
+
|
1566
|
+
if when_constr.context.lvar_env[cond_vars.first].is_a?(AST::Types::Bot)
|
1567
|
+
# Exhaustive
|
1568
|
+
if els
|
1569
|
+
typing.add_error Errors::ElseOnExhaustiveCase.new(node: els, type: cond_type)
|
1538
1570
|
end
|
1539
1571
|
else
|
1540
|
-
|
1572
|
+
unless els
|
1573
|
+
types << AST::Builtin.nil_type
|
1574
|
+
end
|
1541
1575
|
end
|
1542
|
-
|
1576
|
+
else
|
1577
|
+
branch_pairs = []
|
1578
|
+
|
1579
|
+
when_constr = constr
|
1543
1580
|
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1581
|
+
whens.each do |clause|
|
1582
|
+
*tests, body = clause.children
|
1583
|
+
|
1584
|
+
test_constr = when_constr
|
1585
|
+
test_envs = []
|
1586
|
+
|
1587
|
+
tests.each do |test|
|
1588
|
+
test_type, test_constr = test_constr.synthesize(test)
|
1589
|
+
truthy_env, falsy_env = interpreter.eval(env: test_constr.context.lvar_env, type: test_type, node: test)
|
1590
|
+
test_envs << truthy_env
|
1591
|
+
test_constr = test_constr.update_lvar_env { falsy_env }
|
1548
1592
|
end
|
1549
1593
|
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1555
|
-
|
1594
|
+
clause_constr = when_constr.update_lvar_env {|env| env.join(*test_envs) }
|
1595
|
+
when_constr = test_constr
|
1596
|
+
|
1597
|
+
if body
|
1598
|
+
branch_pairs << clause_constr
|
1599
|
+
.for_branch(body)
|
1600
|
+
.tap {|constr| typing.add_context_for_node(body, context: constr.context) }
|
1601
|
+
.synthesize(body, hint: hint)
|
1602
|
+
else
|
1603
|
+
branch_pairs << Pair.new(type: AST::Builtin.nil_type, constr: clause_constr)
|
1556
1604
|
end
|
1557
|
-
branch_pairs << constr
|
1558
|
-
.for_branch(els, type_case_override: else_override)
|
1559
|
-
.synthesize(els, hint: hint)
|
1560
|
-
else
|
1561
|
-
branch_pairs << constr.synthesize(els, hint: hint)
|
1562
1605
|
end
|
1563
|
-
end
|
1564
1606
|
|
1565
|
-
|
1566
|
-
|
1607
|
+
if els
|
1608
|
+
branch_pairs << when_constr.synthesize(els, hint: hint)
|
1609
|
+
end
|
1610
|
+
|
1611
|
+
types = branch_pairs.map(&:type)
|
1612
|
+
constrs = branch_pairs.map(&:constr)
|
1567
1613
|
|
1568
|
-
|
1569
|
-
|
1614
|
+
unless els
|
1615
|
+
types << AST::Builtin.nil_type
|
1616
|
+
end
|
1570
1617
|
end
|
1571
1618
|
|
1572
1619
|
constr = constr.update_lvar_env do |env|
|
@@ -1579,7 +1626,7 @@ module Steep
|
|
1579
1626
|
when :rescue
|
1580
1627
|
yield_self do
|
1581
1628
|
body, *resbodies, else_node = node.children
|
1582
|
-
body_pair = synthesize(body) if body
|
1629
|
+
body_pair = synthesize(body, hint: hint) if body
|
1583
1630
|
|
1584
1631
|
body_constr = if body_pair
|
1585
1632
|
self.update_lvar_env do |env|
|
@@ -1617,7 +1664,7 @@ module Steep
|
|
1617
1664
|
instance_types = exn_types.map do |type|
|
1618
1665
|
type = expand_alias(type)
|
1619
1666
|
case
|
1620
|
-
when type.is_a?(AST::Types::Name::
|
1667
|
+
when type.is_a?(AST::Types::Name::Singleton)
|
1621
1668
|
to_instance_type(type)
|
1622
1669
|
else
|
1623
1670
|
AST::Builtin.any_type
|
@@ -1631,7 +1678,7 @@ module Steep
|
|
1631
1678
|
resbody_construction = body_constr.for_branch(resbody, type_case_override: type_override)
|
1632
1679
|
|
1633
1680
|
if body
|
1634
|
-
resbody_construction.synthesize(body)
|
1681
|
+
resbody_construction.synthesize(body, hint: hint)
|
1635
1682
|
else
|
1636
1683
|
Pair.new(constr: body_constr, type: AST::Builtin.nil_type)
|
1637
1684
|
end
|
@@ -1641,7 +1688,7 @@ module Steep
|
|
1641
1688
|
resbody_envs = resbody_pairs.map {|pair| pair.context.lvar_env }
|
1642
1689
|
|
1643
1690
|
if else_node
|
1644
|
-
else_pair = (body_pair&.constr || self).for_branch(else_node).synthesize(else_node)
|
1691
|
+
else_pair = (body_pair&.constr || self).for_branch(else_node).synthesize(else_node, hint: hint)
|
1645
1692
|
add_typing(node,
|
1646
1693
|
type: union_type(*[else_pair.type, *resbody_types].compact),
|
1647
1694
|
constr: update_lvar_env {|env| env.join(*resbody_envs, env) })
|
@@ -1657,7 +1704,7 @@ module Steep
|
|
1657
1704
|
klasses, asgn, body = node.children
|
1658
1705
|
synthesize(klasses) if klasses
|
1659
1706
|
synthesize(asgn) if asgn
|
1660
|
-
body_type = synthesize(body).type if body
|
1707
|
+
body_type = synthesize(body, hint: hint).type if body
|
1661
1708
|
add_typing(node, type: body_type)
|
1662
1709
|
end
|
1663
1710
|
|
@@ -1672,19 +1719,62 @@ module Steep
|
|
1672
1719
|
when :masgn
|
1673
1720
|
type_masgn(node)
|
1674
1721
|
|
1722
|
+
when :for
|
1723
|
+
yield_self do
|
1724
|
+
asgn, collection, body = node.children
|
1725
|
+
|
1726
|
+
collection_type, constr = synthesize(collection)
|
1727
|
+
collection_type = expand_self(collection_type)
|
1728
|
+
|
1729
|
+
var_type = case collection_type
|
1730
|
+
when AST::Types::Any
|
1731
|
+
AST::Types::Any.new
|
1732
|
+
else
|
1733
|
+
each = checker.factory.interface(collection_type, private: true).methods[:each]
|
1734
|
+
method_type = (each&.method_types || []).find {|type| type.block && type.block.type.params.first_param }
|
1735
|
+
method_type&.yield_self do |method_type|
|
1736
|
+
method_type.block.type.params.first_param&.type
|
1737
|
+
end
|
1738
|
+
end
|
1739
|
+
|
1740
|
+
if var_type
|
1741
|
+
if body
|
1742
|
+
body_constr = constr.with_updated_context(
|
1743
|
+
lvar_env: constr.context.lvar_env.assign(asgn.children[0].name, node: asgn, type: var_type)
|
1744
|
+
)
|
1745
|
+
|
1746
|
+
typing.add_context_for_body(node, context: body_constr.context)
|
1747
|
+
_, _, body_context = body_constr.synthesize(body)
|
1748
|
+
|
1749
|
+
constr = constr.update_lvar_env {|env| env.join(constr.context.lvar_env, body_context.lvar_env) }
|
1750
|
+
else
|
1751
|
+
constr = self
|
1752
|
+
end
|
1753
|
+
|
1754
|
+
add_typing(node, type: collection_type, constr: constr)
|
1755
|
+
else
|
1756
|
+
fallback_to_any(node) do
|
1757
|
+
Errors::NoMethod.new(
|
1758
|
+
node: node,
|
1759
|
+
method: :each,
|
1760
|
+
type: collection_type
|
1761
|
+
)
|
1762
|
+
end
|
1763
|
+
end
|
1764
|
+
end
|
1675
1765
|
when :while, :until
|
1676
1766
|
yield_self do
|
1677
1767
|
cond, body = node.children
|
1678
|
-
|
1768
|
+
cond_type, constr = synthesize(cond)
|
1679
1769
|
|
1680
|
-
|
1681
|
-
|
1770
|
+
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
|
1771
|
+
truthy_env, falsy_env = interpreter.eval(env: constr.context.lvar_env, node: cond, type: cond_type)
|
1682
1772
|
|
1683
1773
|
case node.type
|
1684
1774
|
when :while
|
1685
|
-
body_env, exit_env =
|
1775
|
+
body_env, exit_env = truthy_env, falsy_env
|
1686
1776
|
when :until
|
1687
|
-
exit_env, body_env =
|
1777
|
+
exit_env, body_env = truthy_env, falsy_env
|
1688
1778
|
end
|
1689
1779
|
|
1690
1780
|
if body
|
@@ -1733,9 +1823,22 @@ module Steep
|
|
1733
1823
|
end
|
1734
1824
|
|
1735
1825
|
when :irange, :erange
|
1736
|
-
|
1737
|
-
|
1738
|
-
|
1826
|
+
begin_node, end_node = node.children
|
1827
|
+
|
1828
|
+
constr = self
|
1829
|
+
begin_type, constr = if begin_node
|
1830
|
+
constr.synthesize(begin_node)
|
1831
|
+
else
|
1832
|
+
[AST::Builtin.nil_type, constr]
|
1833
|
+
end
|
1834
|
+
end_type, constr = if end_node
|
1835
|
+
constr.synthesize(end_node)
|
1836
|
+
else
|
1837
|
+
[AST::Builtin.nil_type, constr]
|
1838
|
+
end
|
1839
|
+
|
1840
|
+
type = AST::Builtin::Range.instance_type(union_type(begin_type, end_type))
|
1841
|
+
add_typing(node, type: type, constr: constr)
|
1739
1842
|
|
1740
1843
|
when :regexp
|
1741
1844
|
each_child_node(node) do |child|
|
@@ -1753,9 +1856,36 @@ module Steep
|
|
1753
1856
|
|
1754
1857
|
when :or_asgn, :and_asgn
|
1755
1858
|
yield_self do
|
1756
|
-
|
1757
|
-
|
1758
|
-
|
1859
|
+
asgn, rhs = node.children
|
1860
|
+
|
1861
|
+
case asgn.type
|
1862
|
+
when :lvasgn
|
1863
|
+
type, constr = synthesize(rhs, hint: hint)
|
1864
|
+
constr.lvasgn(asgn, type)
|
1865
|
+
when :ivasgn
|
1866
|
+
type, constr = synthesize(rhs, hint: hint)
|
1867
|
+
constr.ivasgn(asgn, type)
|
1868
|
+
when :send
|
1869
|
+
rhs_ = node.updated(:send,
|
1870
|
+
[
|
1871
|
+
asgn.children[0],
|
1872
|
+
:"#{asgn.children[1]}=",
|
1873
|
+
asgn.children[2],
|
1874
|
+
rhs
|
1875
|
+
])
|
1876
|
+
node_type = case node.type
|
1877
|
+
when :or_asgn
|
1878
|
+
:or
|
1879
|
+
when :and_asgn
|
1880
|
+
:and
|
1881
|
+
end
|
1882
|
+
node_ = node.updated(node_type, [asgn, rhs_])
|
1883
|
+
|
1884
|
+
synthesize(node_, hint: hint)
|
1885
|
+
else
|
1886
|
+
Steep.logger.error { "#{node.type} with #{asgn.type} lhs is not supported"}
|
1887
|
+
fallback_to_any(node)
|
1888
|
+
end
|
1759
1889
|
end
|
1760
1890
|
|
1761
1891
|
when :defined?
|
@@ -1802,8 +1932,8 @@ module Steep
|
|
1802
1932
|
param_type = hint.params.required[0]
|
1803
1933
|
interface = checker.factory.interface(param_type, private: true)
|
1804
1934
|
method = interface.methods[value.children[0]]
|
1805
|
-
if method
|
1806
|
-
return_types = method.
|
1935
|
+
if method
|
1936
|
+
return_types = method.method_types.select {|method_type|
|
1807
1937
|
method_type.params.each_type.count == 0
|
1808
1938
|
}.map(&:return_type)
|
1809
1939
|
|
@@ -1831,9 +1961,50 @@ module Steep
|
|
1831
1961
|
add_typing node, type: AST::Builtin.any_type
|
1832
1962
|
end
|
1833
1963
|
|
1834
|
-
when :
|
1964
|
+
when :cvasgn
|
1965
|
+
name, rhs = node.children
|
1966
|
+
|
1967
|
+
type, constr = synthesize(rhs, hint: hint)
|
1968
|
+
|
1969
|
+
var_type = if module_context&.class_variables
|
1970
|
+
module_context.class_variables[name]&.yield_self {|ty| checker.factory.type(ty) }
|
1971
|
+
end
|
1972
|
+
|
1973
|
+
if var_type
|
1974
|
+
result = constr.check_relation(sub_type: type, super_type: var_type)
|
1975
|
+
|
1976
|
+
if result.success?
|
1977
|
+
add_typing node, type: type, constr: constr
|
1978
|
+
else
|
1979
|
+
fallback_to_any node do
|
1980
|
+
Errors::IncompatibleAssignment.new(node: node,
|
1981
|
+
lhs_type: var_type,
|
1982
|
+
rhs_type: type,
|
1983
|
+
result: result)
|
1984
|
+
end
|
1985
|
+
end
|
1986
|
+
else
|
1987
|
+
fallback_to_any(node)
|
1988
|
+
end
|
1989
|
+
|
1990
|
+
when :cvar
|
1991
|
+
name = node.children[0]
|
1992
|
+
var_type = if module_context&.class_variables
|
1993
|
+
module_context.class_variables[name]&.yield_self {|ty| checker.factory.type(ty) }
|
1994
|
+
end
|
1995
|
+
|
1996
|
+
if var_type
|
1997
|
+
add_typing node, type: var_type
|
1998
|
+
else
|
1999
|
+
fallback_to_any node
|
2000
|
+
end
|
2001
|
+
|
2002
|
+
when :alias
|
2003
|
+
add_typing node, type: AST::Builtin.nil_type
|
2004
|
+
|
2005
|
+
when :splat
|
1835
2006
|
yield_self do
|
1836
|
-
Steep.logger.
|
2007
|
+
Steep.logger.warn { "Unsupported node #{node.type} (#{node.location.expression.source_buffer.name}:#{node.location.expression.line})" }
|
1837
2008
|
|
1838
2009
|
each_child_node node do |child|
|
1839
2010
|
synthesize(child)
|
@@ -1842,8 +2013,18 @@ module Steep
|
|
1842
2013
|
add_typing node, type: AST::Builtin.any_type
|
1843
2014
|
end
|
1844
2015
|
|
2016
|
+
when :args
|
2017
|
+
constr = self
|
2018
|
+
|
2019
|
+
each_child_node(node) do |child|
|
2020
|
+
_, constr = constr.synthesize(child)
|
2021
|
+
end
|
2022
|
+
|
2023
|
+
add_typing node, type: AST::Builtin.any_type, constr: constr
|
2024
|
+
|
1845
2025
|
else
|
1846
2026
|
raise "Unexpected node: #{node.inspect}, #{node.location.expression}"
|
2027
|
+
|
1847
2028
|
end.tap do |pair|
|
1848
2029
|
unless pair.is_a?(Pair) && !pair.type.is_a?(Pair)
|
1849
2030
|
# Steep.logger.error { "result = #{pair.inspect}" }
|
@@ -1883,136 +2064,202 @@ module Steep
|
|
1883
2064
|
add_typing(node, type: ivar_type)
|
1884
2065
|
end
|
1885
2066
|
|
2067
|
+
def masgn_lhs?(lhs)
|
2068
|
+
lhs.children.all? do |a|
|
2069
|
+
asgn_type = if a.type == :splat
|
2070
|
+
a.children[0].type
|
2071
|
+
else
|
2072
|
+
a.type
|
2073
|
+
end
|
2074
|
+
asgn_type == :lvasgn || asgn_type == :ivasgn
|
2075
|
+
end
|
2076
|
+
end
|
2077
|
+
|
2078
|
+
def lvasgn(node, type)
|
2079
|
+
name = node.children[0].name
|
2080
|
+
env = context.lvar_env.assign(name, node: node, type: type) do |declared_type, type, result|
|
2081
|
+
typing.add_error(
|
2082
|
+
Errors::IncompatibleAssignment.new(node: node,
|
2083
|
+
lhs_type: declared_type,
|
2084
|
+
rhs_type: type,
|
2085
|
+
result: result)
|
2086
|
+
)
|
2087
|
+
end
|
2088
|
+
|
2089
|
+
add_typing(node, type: type, constr: with_updated_context(lvar_env: env))
|
2090
|
+
end
|
2091
|
+
|
2092
|
+
def ivasgn(node, type)
|
2093
|
+
ivar = node.children[0]
|
2094
|
+
|
2095
|
+
type_env.assign(ivar: ivar, type: type, self_type: self_type) do |error|
|
2096
|
+
case error
|
2097
|
+
when Subtyping::Result::Failure
|
2098
|
+
var_type = type_env.get(ivar: ivar)
|
2099
|
+
typing.add_error(Errors::IncompatibleAssignment.new(node: node,
|
2100
|
+
lhs_type: var_type,
|
2101
|
+
rhs_type: type,
|
2102
|
+
result: error))
|
2103
|
+
when nil
|
2104
|
+
fallback_to_any node
|
2105
|
+
end
|
2106
|
+
end
|
2107
|
+
|
2108
|
+
add_typing(node, type: type)
|
2109
|
+
end
|
2110
|
+
|
1886
2111
|
def type_masgn(node)
|
1887
2112
|
lhs, rhs = node.children
|
1888
2113
|
rhs_pair = synthesize(rhs)
|
1889
|
-
rhs_type =
|
2114
|
+
rhs_type = deep_expand_alias(rhs_pair.type)
|
1890
2115
|
|
1891
2116
|
constr = rhs_pair.constr
|
1892
2117
|
|
1893
|
-
|
1894
|
-
|
1895
|
-
|
1896
|
-
|
2118
|
+
unless masgn_lhs?(lhs)
|
2119
|
+
Steep.logger.error("Unsupported masgn lhs node: only lvasgn, ivasgn, and splat are supported")
|
2120
|
+
_, constr = constr.fallback_to_any(lhs)
|
2121
|
+
return add_typing(node, type: rhs_type, constr: constr)
|
2122
|
+
end
|
1897
2123
|
|
1898
|
-
|
1899
|
-
|
1900
|
-
|
1901
|
-
|
1902
|
-
|
1903
|
-
|
1904
|
-
|
1905
|
-
|
1906
|
-
|
1907
|
-
|
1908
|
-
|
1909
|
-
|
1910
|
-
|
1911
|
-
|
1912
|
-
|
1913
|
-
|
1914
|
-
|
1915
|
-
|
1916
|
-
|
1917
|
-
|
2124
|
+
falseys, truthys = partition_flatten_types(rhs_type) do |type|
|
2125
|
+
type.is_a?(AST::Types::Nil) || (type.is_a?(AST::Types::Literal) && type.value == false)
|
2126
|
+
end
|
2127
|
+
|
2128
|
+
unwrap_rhs_type = AST::Types::Union.build(types: truthys)
|
2129
|
+
|
2130
|
+
case
|
2131
|
+
when unwrap_rhs_type.is_a?(AST::Types::Tuple) || (rhs.type == :array && rhs.children.none? {|n| n.type == :splat })
|
2132
|
+
tuple_types = if unwrap_rhs_type.is_a?(AST::Types::Tuple)
|
2133
|
+
unwrap_rhs_type.types.dup
|
2134
|
+
else
|
2135
|
+
rhs.children.map do |node|
|
2136
|
+
typing.type_of(node: node)
|
2137
|
+
end
|
2138
|
+
end
|
2139
|
+
|
2140
|
+
assignment_nodes = lhs.children.dup
|
2141
|
+
leading_assignments = []
|
2142
|
+
trailing_assignments = []
|
2143
|
+
|
2144
|
+
until assignment_nodes.empty?
|
2145
|
+
cursor = assignment_nodes.first
|
2146
|
+
|
2147
|
+
if cursor.type == :splat
|
2148
|
+
break
|
2149
|
+
else
|
2150
|
+
leading_assignments << assignment_nodes.shift
|
1918
2151
|
end
|
2152
|
+
end
|
1919
2153
|
|
1920
|
-
|
2154
|
+
until assignment_nodes.empty?
|
2155
|
+
cursor = assignment_nodes.last
|
1921
2156
|
|
1922
|
-
|
1923
|
-
|
2157
|
+
if cursor.type == :splat
|
2158
|
+
break
|
2159
|
+
else
|
2160
|
+
trailing_assignments.unshift assignment_nodes.pop
|
2161
|
+
end
|
2162
|
+
end
|
1924
2163
|
|
1925
|
-
|
1926
|
-
|
2164
|
+
leading_assignments.each do |asgn|
|
2165
|
+
type = tuple_types.first
|
1927
2166
|
|
1928
|
-
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1933
|
-
Errors::IncompatibleAssignment.new(node: lhs,
|
1934
|
-
lhs_type: declared_type,
|
1935
|
-
rhs_type: type,
|
1936
|
-
result: result)
|
1937
|
-
)
|
1938
|
-
end
|
1939
|
-
add_typing(lhs,
|
1940
|
-
type: ty,
|
1941
|
-
constr: ctr.with_updated_context(lvar_env: env)).constr
|
1942
|
-
when :ivasgn
|
1943
|
-
ivar = lhs.children[0]
|
2167
|
+
if type
|
2168
|
+
tuple_types.shift
|
2169
|
+
else
|
2170
|
+
type = AST::Builtin.nil_type
|
2171
|
+
end
|
1944
2172
|
|
1945
|
-
|
1946
|
-
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
1952
|
-
result: error))
|
1953
|
-
when nil
|
1954
|
-
fallback_to_any node
|
1955
|
-
end
|
1956
|
-
end
|
2173
|
+
case asgn.type
|
2174
|
+
when :lvasgn
|
2175
|
+
_, constr = constr.lvasgn(asgn, type)
|
2176
|
+
when :ivasgn
|
2177
|
+
_, constr = constr.ivasgn(asgn, type)
|
2178
|
+
end
|
2179
|
+
end
|
1957
2180
|
|
1958
|
-
|
1959
|
-
|
2181
|
+
trailing_assignments.reverse_each do |asgn|
|
2182
|
+
type = tuple_types.last
|
2183
|
+
|
2184
|
+
if type
|
2185
|
+
tuple_types.pop
|
2186
|
+
else
|
2187
|
+
type = AST::Builtin.nil_type
|
1960
2188
|
end
|
1961
2189
|
|
1962
|
-
|
2190
|
+
case asgn.type
|
2191
|
+
when :lvasgn
|
2192
|
+
_, constr = constr.lvasgn(asgn, type)
|
2193
|
+
when :ivasgn
|
2194
|
+
_, constr = constr.ivasgn(asgn, type)
|
2195
|
+
end
|
2196
|
+
end
|
1963
2197
|
|
1964
|
-
|
1965
|
-
|
2198
|
+
element_type = if tuple_types.empty?
|
2199
|
+
AST::Builtin.nil_type
|
2200
|
+
else
|
2201
|
+
AST::Types::Union.build(types: tuple_types)
|
2202
|
+
end
|
2203
|
+
array_type = AST::Builtin::Array.instance_type(element_type)
|
1966
2204
|
|
1967
|
-
|
1968
|
-
|
2205
|
+
assignment_nodes.each do |asgn|
|
2206
|
+
case asgn.type
|
2207
|
+
when :splat
|
2208
|
+
case asgn.children[0].type
|
1969
2209
|
when :lvasgn
|
1970
|
-
|
1971
|
-
|
1972
|
-
|
1973
|
-
|
1974
|
-
|
1975
|
-
|
1976
|
-
|
1977
|
-
|
1978
|
-
|
2210
|
+
_, constr = constr.lvasgn(asgn.children[0], array_type)
|
2211
|
+
when :ivasgn
|
2212
|
+
_, constr = constr.ivasgn(asgn.children[0], array_type)
|
2213
|
+
end
|
2214
|
+
when :lvasgn
|
2215
|
+
_, constr = constr.lvasgn(asgn, element_type)
|
2216
|
+
when :ivasgn
|
2217
|
+
_,constr = constr.ivasgn(asgn, element_type)
|
2218
|
+
end
|
2219
|
+
end
|
1979
2220
|
|
1980
|
-
|
1981
|
-
|
1982
|
-
|
2221
|
+
unless falseys.empty?
|
2222
|
+
constr = constr.update_lvar_env {|lvar_env| self.context.lvar_env.join(lvar_env, self.context.lvar_env)}
|
2223
|
+
end
|
1983
2224
|
|
1984
|
-
|
1985
|
-
ivar = assignment.children[0]
|
2225
|
+
add_typing(node, type: rhs_type, constr: constr)
|
1986
2226
|
|
1987
|
-
|
1988
|
-
|
1989
|
-
|
1990
|
-
|
1991
|
-
|
1992
|
-
|
1993
|
-
|
1994
|
-
|
1995
|
-
when nil
|
1996
|
-
fallback_to_any node
|
1997
|
-
end
|
1998
|
-
end
|
2227
|
+
when flatten_union(unwrap_rhs_type).all? {|type| AST::Builtin::Array.instance_type?(type) }
|
2228
|
+
array_elements = flatten_union(unwrap_rhs_type).map {|type| type.args[0] }
|
2229
|
+
element_type = AST::Types::Union.build(types: array_elements + [AST::Builtin.nil_type])
|
2230
|
+
|
2231
|
+
constr = lhs.children.inject(constr) do |constr, assignment|
|
2232
|
+
case assignment.type
|
2233
|
+
when :lvasgn
|
2234
|
+
_, constr = constr.lvasgn(assignment, element_type)
|
1999
2235
|
|
2000
|
-
|
2236
|
+
when :ivasgn
|
2237
|
+
_, constr = constr.ivasgn(assignment, element_type)
|
2238
|
+
when :splat
|
2239
|
+
case assignment.children[0].type
|
2240
|
+
when :lvasgn
|
2241
|
+
_, constr = constr.lvasgn(assignment.children[0], unwrap_rhs_type)
|
2242
|
+
when :ivasgn
|
2243
|
+
_, constr = constr.ivasgn(assignment.children[0], unwrap_rhs_type)
|
2244
|
+
else
|
2245
|
+
raise
|
2001
2246
|
end
|
2002
2247
|
end
|
2003
2248
|
|
2004
|
-
|
2005
|
-
|
2006
|
-
when rhs_type.is_a?(AST::Types::Any)
|
2007
|
-
fallback_to_any(node)
|
2249
|
+
constr
|
2250
|
+
end
|
2008
2251
|
|
2009
|
-
|
2010
|
-
|
2011
|
-
fallback_to_any(node)
|
2252
|
+
unless falseys.empty?
|
2253
|
+
constr = constr.update_lvar_env {|lvar_env| self.context.lvar_env.join(lvar_env, self.context.lvar_env)}
|
2012
2254
|
end
|
2255
|
+
|
2256
|
+
add_typing(node, type: rhs_type, constr: constr)
|
2013
2257
|
else
|
2014
|
-
|
2015
|
-
|
2258
|
+
unless rhs_type.is_a?(AST::Types::Any)
|
2259
|
+
Steep.logger.error("Unsupported masgn rhs type: array or tuple is supported (#{rhs_type})")
|
2260
|
+
end
|
2261
|
+
_, constr = constr.fallback_to_any(lhs)
|
2262
|
+
add_typing(node, type: rhs_type, constr: constr)
|
2016
2263
|
end
|
2017
2264
|
end
|
2018
2265
|
|
@@ -2040,7 +2287,7 @@ module Steep
|
|
2040
2287
|
|
2041
2288
|
def type_send(node, send_node:, block_params:, block_body:, unwrap: false)
|
2042
2289
|
receiver, method_name, *arguments = send_node.children
|
2043
|
-
receiver_type = receiver ? synthesize(receiver)
|
2290
|
+
receiver_type, constr = receiver ? synthesize(receiver) : [AST::Types::Self.new, self]
|
2044
2291
|
|
2045
2292
|
if unwrap
|
2046
2293
|
receiver_type = unwrap(receiver_type)
|
@@ -2048,74 +2295,80 @@ module Steep
|
|
2048
2295
|
|
2049
2296
|
receiver_type = expand_alias(receiver_type)
|
2050
2297
|
|
2051
|
-
|
2052
|
-
|
2053
|
-
|
2298
|
+
type, constr = case receiver_type
|
2299
|
+
when AST::Types::Any
|
2300
|
+
each_child_node(send_node) do |child|
|
2301
|
+
unless child.equal?(receiver)
|
2302
|
+
_, constr = constr.synthesize(child)
|
2303
|
+
end
|
2304
|
+
end
|
2054
2305
|
|
2055
|
-
|
2056
|
-
fallback_to_any node
|
2306
|
+
add_typing node, type: AST::Builtin.any_type
|
2057
2307
|
|
2058
|
-
|
2059
|
-
|
2060
|
-
Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2061
|
-
end
|
2308
|
+
when nil
|
2309
|
+
fallback_to_any node
|
2062
2310
|
|
2063
|
-
|
2064
|
-
|
2065
|
-
|
2066
|
-
|
2067
|
-
fallback_to_any node do
|
2068
|
-
Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2069
|
-
end
|
2070
|
-
else
|
2071
|
-
begin
|
2072
|
-
interface = checker.factory.interface(receiver_type,
|
2073
|
-
private: !receiver,
|
2074
|
-
self_type: expanded_receiver_type)
|
2075
|
-
|
2076
|
-
method = interface.methods[method_name]
|
2077
|
-
|
2078
|
-
if method
|
2079
|
-
args = TypeInference::SendArgs.from_nodes(arguments)
|
2080
|
-
return_type, constr, _ = type_method_call(node,
|
2081
|
-
method: method,
|
2082
|
-
method_name: method_name,
|
2083
|
-
args: args,
|
2084
|
-
block_params: block_params,
|
2085
|
-
block_body: block_body,
|
2086
|
-
receiver_type: receiver_type,
|
2087
|
-
topdown_hint: true)
|
2088
|
-
|
2089
|
-
add_typing node, type: return_type, constr: constr
|
2090
|
-
else
|
2091
|
-
fallback_to_any node do
|
2092
|
-
Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
|
2093
|
-
end
|
2094
|
-
end
|
2095
|
-
rescue => exn
|
2096
|
-
case exn
|
2097
|
-
when RBS::NoTypeFoundError, RBS::NoMixinFoundError, RBS::NoSuperclassFoundError, RBS::InvalidTypeApplicationError
|
2098
|
-
# ignore known RBS errors.
|
2099
|
-
else
|
2100
|
-
Steep.log_error(exn, message: "Unexpected error in #type_send: #{exn.message} (#{exn.class})")
|
2101
|
-
end
|
2311
|
+
when AST::Types::Void, AST::Types::Bot, AST::Types::Top
|
2312
|
+
fallback_to_any node do
|
2313
|
+
Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2314
|
+
end
|
2102
2315
|
|
2103
|
-
|
2104
|
-
|
2105
|
-
|
2106
|
-
|
2107
|
-
|
2108
|
-
|
2316
|
+
else
|
2317
|
+
case expanded_receiver_type = expand_self(receiver_type)
|
2318
|
+
when AST::Types::Self
|
2319
|
+
Steep.logger.debug { "`self` type cannot be resolved to concrete type" }
|
2320
|
+
fallback_to_any node do
|
2321
|
+
Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2322
|
+
end
|
2323
|
+
else
|
2324
|
+
begin
|
2325
|
+
interface = checker.factory.interface(receiver_type,
|
2326
|
+
private: !receiver,
|
2327
|
+
self_type: expanded_receiver_type)
|
2328
|
+
|
2329
|
+
method = interface.methods[method_name]
|
2330
|
+
|
2331
|
+
if method
|
2332
|
+
args = TypeInference::SendArgs.from_nodes(arguments)
|
2333
|
+
return_type, constr, _ = constr.type_method_call(node,
|
2334
|
+
method: method,
|
2335
|
+
method_name: method_name,
|
2336
|
+
args: args,
|
2337
|
+
block_params: block_params,
|
2338
|
+
block_body: block_body,
|
2339
|
+
receiver_type: receiver_type,
|
2340
|
+
topdown_hint: true)
|
2341
|
+
|
2342
|
+
add_typing node, type: return_type, constr: constr
|
2343
|
+
else
|
2344
|
+
fallback_to_any node do
|
2345
|
+
Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
|
2346
|
+
end
|
2347
|
+
end
|
2348
|
+
rescue => exn
|
2349
|
+
case exn
|
2350
|
+
when RBS::NoTypeFoundError, RBS::NoMixinFoundError, RBS::NoSuperclassFoundError, RBS::InvalidTypeApplicationError
|
2351
|
+
# ignore known RBS errors.
|
2352
|
+
else
|
2353
|
+
Steep.log_error(exn, message: "Unexpected error in #type_send: #{exn.message} (#{exn.class})")
|
2354
|
+
end
|
2355
|
+
|
2356
|
+
fallback_to_any node do
|
2357
|
+
Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
|
2358
|
+
end
|
2359
|
+
end
|
2360
|
+
end
|
2361
|
+
end
|
2109
2362
|
|
2110
|
-
case
|
2363
|
+
case type
|
2111
2364
|
when nil, Errors::Base
|
2112
2365
|
arguments.each do |arg|
|
2113
2366
|
unless typing.has_type?(arg)
|
2114
2367
|
if arg.type == :splat
|
2115
|
-
type = synthesize(arg.children[0])
|
2368
|
+
type, constr = constr.synthesize(arg.children[0])
|
2116
2369
|
add_typing(arg, type: AST::Builtin::Array.instance_type(type))
|
2117
2370
|
else
|
2118
|
-
synthesize(arg)
|
2371
|
+
_, constr = constr.synthesize(arg)
|
2119
2372
|
end
|
2120
2373
|
end
|
2121
2374
|
end
|
@@ -2137,7 +2390,7 @@ module Steep
|
|
2137
2390
|
end
|
2138
2391
|
end
|
2139
2392
|
else
|
2140
|
-
|
2393
|
+
Pair.new(type: type, constr: constr)
|
2141
2394
|
end
|
2142
2395
|
end
|
2143
2396
|
|
@@ -2204,139 +2457,68 @@ module Steep
|
|
2204
2457
|
def type_method_call(node, method_name:, receiver_type:, method:, args:, block_params:, block_body:, topdown_hint:)
|
2205
2458
|
node_range = node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
|
2206
2459
|
|
2207
|
-
|
2208
|
-
|
2209
|
-
|
2210
|
-
|
2460
|
+
results = method.method_types.flat_map do |method_type|
|
2461
|
+
Steep.logger.tagged method_type.to_s do
|
2462
|
+
zips = args.zips(method_type.params, method_type.block&.type)
|
2463
|
+
|
2464
|
+
zips.map do |arg_pairs|
|
2211
2465
|
typing.new_child(node_range) do |child_typing|
|
2212
|
-
with_new_typing(child_typing).
|
2213
|
-
|
2214
|
-
|
2215
|
-
|
2216
|
-
|
2217
|
-
|
2218
|
-
|
2219
|
-
|
2220
|
-
|
2221
|
-
|
2466
|
+
ret = self.with_new_typing(child_typing).try_method_type(
|
2467
|
+
node,
|
2468
|
+
receiver_type: receiver_type,
|
2469
|
+
method_type: method_type,
|
2470
|
+
args: args,
|
2471
|
+
arg_pairs: arg_pairs,
|
2472
|
+
block_params: block_params,
|
2473
|
+
block_body: block_body,
|
2474
|
+
child_typing: child_typing,
|
2475
|
+
topdown_hint: topdown_hint
|
2476
|
+
)
|
2222
2477
|
|
2223
|
-
|
2224
|
-
constr.typing.save!
|
2225
|
-
[type,
|
2226
|
-
update_lvar_env { constr.context.lvar_env },
|
2227
|
-
error]
|
2228
|
-
else
|
2229
|
-
types = results.map(&:first)
|
2478
|
+
raise unless ret.is_a?(Array) && ret[1].is_a?(TypeConstruction)
|
2230
2479
|
|
2231
|
-
|
2232
|
-
constr.typing.save!
|
2480
|
+
result, constr = ret
|
2233
2481
|
|
2234
|
-
|
2235
|
-
|
2236
|
-
nil]
|
2482
|
+
[result, constr, method_type]
|
2483
|
+
end
|
2237
2484
|
end
|
2238
2485
|
end
|
2486
|
+
end
|
2239
2487
|
|
2240
|
-
|
2241
|
-
|
2242
|
-
|
2243
|
-
|
2244
|
-
|
2488
|
+
unless results.empty?
|
2489
|
+
result, constr, method_type = results.find {|result, _, _| !result.is_a?(Errors::Base) } || results.last
|
2490
|
+
else
|
2491
|
+
method_type = method.method_types.last
|
2492
|
+
constr = self.with_new_typing(typing.new_child(node_range))
|
2493
|
+
result = Errors::IncompatibleArguments.new(node: node, receiver_type: receiver_type, method_type: method_type)
|
2494
|
+
end
|
2495
|
+
constr.typing.save!
|
2496
|
+
|
2497
|
+
case result
|
2498
|
+
when Errors::Base
|
2499
|
+
if method.method_types.size == 1
|
2500
|
+
typing.add_error result
|
2501
|
+
type = case method_type.return_type
|
2502
|
+
when AST::Types::Var
|
2503
|
+
AST::Builtin.any_type
|
2504
|
+
else
|
2505
|
+
method_type.return_type
|
2506
|
+
end
|
2507
|
+
else
|
2508
|
+
typing.add_error Errors::UnresolvedOverloading.new(node: node,
|
2509
|
+
receiver_type: expand_self(receiver_type),
|
2245
2510
|
method_name: method_name,
|
2246
|
-
|
2247
|
-
|
2248
|
-
args: args,
|
2249
|
-
block_params: block_params,
|
2250
|
-
block_body: block_body,
|
2251
|
-
topdown_hint: false)
|
2252
|
-
end
|
2253
|
-
end
|
2254
|
-
|
2255
|
-
successes = results.reject {|_, _, error| error }
|
2256
|
-
unless successes.empty?
|
2257
|
-
types = successes.map(&:first)
|
2258
|
-
constr = successes[0][1]
|
2259
|
-
constr.typing.save!
|
2260
|
-
|
2261
|
-
[AST::Types::Intersection.build(types: types),
|
2262
|
-
update_lvar_env { constr.context.lvar_env },
|
2263
|
-
nil]
|
2264
|
-
else
|
2265
|
-
type, constr, error = results.first
|
2266
|
-
constr.typing.save!
|
2267
|
-
|
2268
|
-
[type,
|
2269
|
-
update_lvar_env { constr.context.lvar_env },
|
2270
|
-
error]
|
2271
|
-
end
|
2511
|
+
method_types: method.method_types)
|
2512
|
+
type = AST::Builtin.any_type
|
2272
2513
|
end
|
2273
2514
|
|
2274
|
-
|
2275
|
-
|
2276
|
-
|
2277
|
-
|
2278
|
-
|
2279
|
-
|
2280
|
-
|
2281
|
-
typing.new_child(node_range) do |child_typing|
|
2282
|
-
ret = self.with_new_typing(child_typing).try_method_type(
|
2283
|
-
node,
|
2284
|
-
receiver_type: receiver_type,
|
2285
|
-
method_type: method_type,
|
2286
|
-
args: args,
|
2287
|
-
arg_pairs: arg_pairs,
|
2288
|
-
block_params: block_params,
|
2289
|
-
block_body: block_body,
|
2290
|
-
child_typing: child_typing,
|
2291
|
-
topdown_hint: topdown_hint
|
2292
|
-
)
|
2293
|
-
|
2294
|
-
raise unless ret.is_a?(Array) && ret[1].is_a?(TypeConstruction)
|
2295
|
-
|
2296
|
-
result, constr = ret
|
2297
|
-
|
2298
|
-
[result, constr, method_type]
|
2299
|
-
end
|
2300
|
-
end
|
2301
|
-
end
|
2302
|
-
end
|
2303
|
-
|
2304
|
-
unless results.empty?
|
2305
|
-
result, constr, method_type = results.find {|result, _, _| !result.is_a?(Errors::Base) } || results.last
|
2306
|
-
else
|
2307
|
-
method_type = method.types.last
|
2308
|
-
constr = self.with_new_typing(typing.new_child(node_range))
|
2309
|
-
result = Errors::IncompatibleArguments.new(node: node, receiver_type: receiver_type, method_type: method_type)
|
2310
|
-
end
|
2311
|
-
constr.typing.save!
|
2312
|
-
|
2313
|
-
case result
|
2314
|
-
when Errors::Base
|
2315
|
-
if method.types.size == 1
|
2316
|
-
typing.add_error result
|
2317
|
-
type = case method_type.return_type
|
2318
|
-
when AST::Types::Var
|
2319
|
-
AST::Builtin.any_type
|
2320
|
-
else
|
2321
|
-
method_type.return_type
|
2322
|
-
end
|
2323
|
-
else
|
2324
|
-
typing.add_error Errors::UnresolvedOverloading.new(node: node,
|
2325
|
-
receiver_type: expand_self(receiver_type),
|
2326
|
-
method_name: method_name,
|
2327
|
-
method_types: method.types)
|
2328
|
-
type = AST::Builtin.any_type
|
2329
|
-
end
|
2330
|
-
|
2331
|
-
[type,
|
2332
|
-
update_lvar_env { constr.context.lvar_env },
|
2333
|
-
result]
|
2334
|
-
else # Type
|
2335
|
-
[result,
|
2336
|
-
update_lvar_env { constr.context.lvar_env },
|
2337
|
-
nil]
|
2338
|
-
end
|
2339
|
-
end
|
2515
|
+
[type,
|
2516
|
+
update_lvar_env { constr.context.lvar_env },
|
2517
|
+
result]
|
2518
|
+
else # Type
|
2519
|
+
[result,
|
2520
|
+
update_lvar_env { constr.context.lvar_env },
|
2521
|
+
nil]
|
2340
2522
|
end
|
2341
2523
|
end
|
2342
2524
|
|
@@ -2523,16 +2705,40 @@ module Steep
|
|
2523
2705
|
if block_params && method_type.block
|
2524
2706
|
block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
|
2525
2707
|
block_params_ = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
|
2526
|
-
block_param_hint = block_params_.params_type(
|
2527
|
-
hint: topdown_hint ? method_type.block.type.params : nil
|
2528
|
-
)
|
2529
2708
|
|
2530
|
-
|
2531
|
-
|
2532
|
-
|
2533
|
-
|
2534
|
-
|
2535
|
-
|
2709
|
+
unless block_params_
|
2710
|
+
return [
|
2711
|
+
Errors::UnsupportedSyntax.new(
|
2712
|
+
node: block_params,
|
2713
|
+
message: "Unsupported block params pattern, probably masgn?"
|
2714
|
+
),
|
2715
|
+
constr
|
2716
|
+
]
|
2717
|
+
end
|
2718
|
+
|
2719
|
+
pairs = block_params_.zip(method_type.block.type.params)
|
2720
|
+
|
2721
|
+
unless pairs
|
2722
|
+
return [
|
2723
|
+
Errors::IncompatibleBlockParameters.new(node: node, method_type: method_type),
|
2724
|
+
constr
|
2725
|
+
]
|
2726
|
+
end
|
2727
|
+
|
2728
|
+
pairs.each do |param, type|
|
2729
|
+
if param.type
|
2730
|
+
check_relation(sub_type: type, super_type: param.type, constraints: constraints).else do |result|
|
2731
|
+
return [
|
2732
|
+
Errors::IncompatibleAssignment.new(
|
2733
|
+
node: param.node,
|
2734
|
+
lhs_type: param.type,
|
2735
|
+
rhs_type: type,
|
2736
|
+
result: result
|
2737
|
+
),
|
2738
|
+
constr
|
2739
|
+
]
|
2740
|
+
end
|
2741
|
+
end
|
2536
2742
|
end
|
2537
2743
|
end
|
2538
2744
|
|
@@ -2683,7 +2889,7 @@ module Steep
|
|
2683
2889
|
decls = param_types_hash.each.with_object({}) do |(name, type), hash|
|
2684
2890
|
hash[name] = TypeInference::LocalVariableTypeEnv::Entry.new(type: type)
|
2685
2891
|
end
|
2686
|
-
env.update(
|
2892
|
+
env.except(decls.keys).update(assigned_types: decls)
|
2687
2893
|
end.annotate(block_annotations)
|
2688
2894
|
|
2689
2895
|
break_type = if block_annotations.break_type
|
@@ -2826,7 +3032,7 @@ module Steep
|
|
2826
3032
|
end
|
2827
3033
|
|
2828
3034
|
def nested_namespace_for_module(module_name)
|
2829
|
-
if module_name.relative?
|
3035
|
+
if module_name.namespace.relative?
|
2830
3036
|
(current_namespace + module_name.namespace).append(module_name.name)
|
2831
3037
|
else
|
2832
3038
|
module_name
|
@@ -2835,7 +3041,7 @@ module Steep
|
|
2835
3041
|
|
2836
3042
|
def absolute_name(module_name)
|
2837
3043
|
if current_namespace
|
2838
|
-
module_name.
|
3044
|
+
module_name.with_prefix(current_namespace)
|
2839
3045
|
else
|
2840
3046
|
module_name.absolute!
|
2841
3047
|
end
|
@@ -2853,7 +3059,7 @@ module Steep
|
|
2853
3059
|
end
|
2854
3060
|
|
2855
3061
|
def validate_method_definitions(node, module_name)
|
2856
|
-
module_name_1 =
|
3062
|
+
module_name_1 = module_name.name
|
2857
3063
|
member_decl_count = checker.factory.env.class_decls[module_name_1].decls.count {|d| d.decl.each_member.count > 0 }
|
2858
3064
|
|
2859
3065
|
return unless member_decl_count == 1
|
@@ -3001,20 +3207,31 @@ module Steep
|
|
3001
3207
|
end
|
3002
3208
|
end
|
3003
3209
|
|
3004
|
-
def deep_expand_alias(type,
|
3005
|
-
|
3210
|
+
def deep_expand_alias(type, &block)
|
3211
|
+
checker.factory.deep_expand_alias(type, &block)
|
3212
|
+
end
|
3006
3213
|
|
3007
|
-
|
3008
|
-
|
3009
|
-
|
3010
|
-
else
|
3011
|
-
type
|
3012
|
-
end
|
3214
|
+
def flatten_union(type)
|
3215
|
+
checker.factory.flatten_union(type)
|
3216
|
+
end
|
3013
3217
|
|
3014
|
-
|
3015
|
-
|
3016
|
-
|
3017
|
-
|
3218
|
+
def select_flatten_types(type, &block)
|
3219
|
+
types = flatten_union(deep_expand_alias(type))
|
3220
|
+
types.select(&block)
|
3221
|
+
end
|
3222
|
+
|
3223
|
+
def partition_flatten_types(type, &block)
|
3224
|
+
types = flatten_union(deep_expand_alias(type))
|
3225
|
+
types.partition(&block)
|
3226
|
+
end
|
3227
|
+
|
3228
|
+
def flatten_array_elements(type)
|
3229
|
+
flatten_union(deep_expand_alias(type)).flat_map do |type|
|
3230
|
+
if AST::Builtin::Array.instance_type?(type)
|
3231
|
+
type.args
|
3232
|
+
else
|
3233
|
+
[type]
|
3234
|
+
end
|
3018
3235
|
end
|
3019
3236
|
end
|
3020
3237
|
|
@@ -3056,8 +3273,8 @@ module Steep
|
|
3056
3273
|
|
3057
3274
|
def to_instance_type(type, args: nil)
|
3058
3275
|
args = args || case type
|
3059
|
-
when AST::Types::Name::
|
3060
|
-
checker.factory.env.class_decls[
|
3276
|
+
when AST::Types::Name::Singleton
|
3277
|
+
checker.factory.env.class_decls[type.name].type_params.each.map { AST::Builtin.any_type }
|
3061
3278
|
else
|
3062
3279
|
raise "unexpected type to to_instance_type: #{type}"
|
3063
3280
|
end
|
@@ -3065,6 +3282,47 @@ module Steep
|
|
3065
3282
|
AST::Types::Name::Instance.new(name: type.name, args: args)
|
3066
3283
|
end
|
3067
3284
|
|
3285
|
+
def try_tuple_type(node, hint)
|
3286
|
+
if node.children.size != hint.types.size
|
3287
|
+
return
|
3288
|
+
end
|
3289
|
+
|
3290
|
+
constr = self
|
3291
|
+
element_types = []
|
3292
|
+
|
3293
|
+
each_child_node(node).with_index do |child, index|
|
3294
|
+
type, constr = constr.synthesize(child, hint: hint.types[index])
|
3295
|
+
element_types << type
|
3296
|
+
end
|
3297
|
+
|
3298
|
+
constr.add_typing(node, type: AST::Types::Tuple.new(types: element_types))
|
3299
|
+
end
|
3300
|
+
|
3301
|
+
def try_array_type(node, hint)
|
3302
|
+
element_hint = hint ? hint.args[0] : nil
|
3303
|
+
|
3304
|
+
constr = self
|
3305
|
+
element_types = []
|
3306
|
+
|
3307
|
+
each_child_node(node) do |child|
|
3308
|
+
case child.type
|
3309
|
+
when :splat
|
3310
|
+
type, constr = constr.synthesize(child.children[0], hint: hint)
|
3311
|
+
if AST::Builtin::Array.instance_type?(type)
|
3312
|
+
element_types << type.args[0]
|
3313
|
+
else
|
3314
|
+
element_types.push(*flatten_array_elements(type))
|
3315
|
+
end
|
3316
|
+
else
|
3317
|
+
type, constr = constr.synthesize(child, hint: element_hint)
|
3318
|
+
element_types << type
|
3319
|
+
end
|
3320
|
+
end
|
3321
|
+
|
3322
|
+
element_type = AST::Types::Union.build(types: element_types)
|
3323
|
+
constr.add_typing(node, type: AST::Builtin::Array.instance_type(element_type))
|
3324
|
+
end
|
3325
|
+
|
3068
3326
|
def try_hash_type(node, hint)
|
3069
3327
|
case hint
|
3070
3328
|
when AST::Types::Record
|