steep 0.22.0 → 0.28.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 -1
- data/bin/smoke_runner.rb +3 -4
- data/lib/steep.rb +1 -1
- data/lib/steep/ast/builtin.rb +2 -20
- 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 +106 -55
- 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/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 +383 -92
- data/lib/steep/interface/substitution.rb +48 -6
- data/lib/steep/project/completion_provider.rb +1 -1
- data/lib/steep/project/hover_content.rb +1 -1
- 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/source.rb +4 -3
- data/lib/steep/subtyping/check.rb +49 -60
- data/lib/steep/type_construction.rb +629 -366
- data/lib/steep/type_inference/block_params.rb +5 -0
- data/lib/steep/type_inference/constant_env.rb +1 -1
- 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/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/steep.gemspec +1 -1
- metadata +5 -5
@@ -26,7 +26,32 @@ module Steep
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.empty
|
29
|
-
new(dictionary: {},
|
29
|
+
new(dictionary: {},
|
30
|
+
instance_type: INSTANCE_TYPE,
|
31
|
+
module_type: CLASS_TYPE,
|
32
|
+
self_type: SELF_TYPE)
|
33
|
+
end
|
34
|
+
|
35
|
+
def empty?
|
36
|
+
dictionary.empty? &&
|
37
|
+
instance_type.is_a?(AST::Types::Instance) &&
|
38
|
+
module_type.is_a?(AST::Types::Class) &&
|
39
|
+
self_type.is_a?(AST::Types::Self)
|
40
|
+
end
|
41
|
+
|
42
|
+
INSTANCE_TYPE = AST::Types::Instance.new
|
43
|
+
CLASS_TYPE = AST::Types::Class.new
|
44
|
+
SELF_TYPE = AST::Types::Self.new
|
45
|
+
|
46
|
+
def domain
|
47
|
+
set = Set.new
|
48
|
+
|
49
|
+
set.merge(dictionary.keys)
|
50
|
+
set << INSTANCE_TYPE unless instance_type.is_a?(AST::Types::Instance)
|
51
|
+
set << CLASS_TYPE unless instance_type.is_a?(AST::Types::Class)
|
52
|
+
set << SELF_TYPE unless instance_type.is_a?(AST::Types::Self)
|
53
|
+
|
54
|
+
set
|
30
55
|
end
|
31
56
|
|
32
57
|
def to_s
|
@@ -65,22 +90,39 @@ module Steep
|
|
65
90
|
|
66
91
|
def except(vars)
|
67
92
|
self.class.new(
|
68
|
-
dictionary: dictionary
|
93
|
+
dictionary: dictionary,
|
69
94
|
instance_type: instance_type,
|
70
95
|
module_type: module_type,
|
71
96
|
self_type: self_type
|
72
|
-
)
|
97
|
+
).except!(vars)
|
73
98
|
end
|
74
99
|
|
75
|
-
def
|
100
|
+
def except!(vars)
|
101
|
+
vars.each do |var|
|
102
|
+
dictionary.delete(var)
|
103
|
+
end
|
104
|
+
|
105
|
+
self
|
106
|
+
end
|
107
|
+
|
108
|
+
def merge!(s, overwrite: false)
|
76
109
|
dictionary.transform_values! {|ty| ty.subst(s) }
|
77
110
|
dictionary.merge!(s.dictionary) do |key, a, b|
|
78
111
|
if a == b
|
79
112
|
a
|
80
113
|
else
|
81
|
-
|
114
|
+
if overwrite
|
115
|
+
b
|
116
|
+
else
|
117
|
+
raise "Duplicated key on merge!: #{key}, #{a}, #{b} (#{self})"
|
118
|
+
end
|
82
119
|
end
|
83
120
|
end
|
121
|
+
|
122
|
+
@instance_type = instance_type.subst(s)
|
123
|
+
@module_type = module_type.subst(s)
|
124
|
+
@self_type = self_type.subst(s)
|
125
|
+
|
84
126
|
self
|
85
127
|
end
|
86
128
|
|
@@ -92,7 +134,7 @@ module Steep
|
|
92
134
|
end
|
93
135
|
|
94
136
|
def add!(v, ty)
|
95
|
-
merge!(Substitution.new(dictionary: { v => ty }, instance_type:
|
137
|
+
merge!(Substitution.new(dictionary: { v => ty }, instance_type: instance_type, module_type: module_type, self_type: self_type))
|
96
138
|
end
|
97
139
|
end
|
98
140
|
end
|
@@ -234,7 +234,7 @@ module Steep
|
|
234
234
|
when AST::Types::Name::Instance
|
235
235
|
type_name = subtyping.factory.type_name_1(type.name)
|
236
236
|
subtyping.factory.definition_builder.build_instance(type_name)
|
237
|
-
when AST::Types::Name::
|
237
|
+
when AST::Types::Name::Singleton
|
238
238
|
type_name = subtyping.factory.type_name_1(type.name)
|
239
239
|
subtyping.factory.definition_builder.build_singleton(type_name)
|
240
240
|
when AST::Types::Name::Interface
|
@@ -92,7 +92,7 @@ module Steep
|
|
92
92
|
method_definition
|
93
93
|
]
|
94
94
|
end
|
95
|
-
when AST::Types::Name::
|
95
|
+
when AST::Types::Name::Singleton
|
96
96
|
method_definition = method_definition_for(factory, receiver_type.name, singleton_method: method_name)
|
97
97
|
if method_definition&.defined_in
|
98
98
|
owner_name = factory.type_name(method_definition.defined_in)
|
data/lib/steep/project/target.rb
CHANGED
@@ -172,6 +172,7 @@ module Steep
|
|
172
172
|
timestamp: Time.now
|
173
173
|
)
|
174
174
|
rescue => exn
|
175
|
+
Steep.log_error exn
|
175
176
|
@status = SignatureOtherErrorStatus.new(error: exn, timestamp: Time.now)
|
176
177
|
end
|
177
178
|
end
|
@@ -194,8 +195,10 @@ module Steep
|
|
194
195
|
type_check_sources = []
|
195
196
|
|
196
197
|
target_sources.each do |file|
|
197
|
-
|
198
|
-
|
198
|
+
Steep.logger.tagged("path=#{file.path}") do
|
199
|
+
if file.type_check(check, timestamp)
|
200
|
+
type_check_sources << file
|
201
|
+
end
|
199
202
|
end
|
200
203
|
end
|
201
204
|
|
@@ -12,6 +12,7 @@ module Steep
|
|
12
12
|
@project = project
|
13
13
|
@reader = reader
|
14
14
|
@writer = writer
|
15
|
+
@shutdown = false
|
15
16
|
end
|
16
17
|
|
17
18
|
def handle_request(request)
|
@@ -28,7 +29,7 @@ module Steep
|
|
28
29
|
Steep.logger.formatter.push_tags(*tags)
|
29
30
|
Steep.logger.tagged "background" do
|
30
31
|
while job = queue.pop
|
31
|
-
handle_job(job)
|
32
|
+
handle_job(job) unless @shutdown
|
32
33
|
end
|
33
34
|
end
|
34
35
|
end
|
@@ -38,11 +39,12 @@ module Steep
|
|
38
39
|
reader.read do |request|
|
39
40
|
case request[:method]
|
40
41
|
when "shutdown"
|
41
|
-
|
42
|
+
@shutdown = true
|
43
|
+
writer.write(id: request[:id], result: nil)
|
42
44
|
when "exit"
|
43
45
|
break
|
44
46
|
else
|
45
|
-
handle_request(request)
|
47
|
+
handle_request(request) unless @shutdown
|
46
48
|
end
|
47
49
|
end
|
48
50
|
ensure
|
data/lib/steep/server/master.rb
CHANGED
@@ -23,6 +23,7 @@ module Steep
|
|
23
23
|
@signature_worker = signature_worker
|
24
24
|
@code_workers = code_workers
|
25
25
|
@worker_to_paths = {}
|
26
|
+
@shutdown_request_id = nil
|
26
27
|
end
|
27
28
|
|
28
29
|
def start
|
@@ -59,7 +60,14 @@ module Steep
|
|
59
60
|
end
|
60
61
|
|
61
62
|
while job = queue.pop
|
62
|
-
|
63
|
+
if @shutdown_request_id
|
64
|
+
if job[:id] == @shutdown_request_id
|
65
|
+
writer.write(job)
|
66
|
+
break
|
67
|
+
end
|
68
|
+
else
|
69
|
+
writer.write(job)
|
70
|
+
end
|
63
71
|
end
|
64
72
|
|
65
73
|
writer.io.close
|
@@ -154,6 +162,7 @@ module Steep
|
|
154
162
|
|
155
163
|
when "shutdown"
|
156
164
|
queue << { id: id, result: nil }
|
165
|
+
@shutdown_request_id = id
|
157
166
|
|
158
167
|
when "exit"
|
159
168
|
queue << nil
|
data/lib/steep/source.rb
CHANGED
@@ -38,7 +38,7 @@ module Steep
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def self.parser
|
41
|
-
::Parser::
|
41
|
+
::Parser::Ruby27.new(Builder.new).tap do |parser|
|
42
42
|
parser.diagnostics.all_errors_are_fatal = true
|
43
43
|
parser.diagnostics.ignore_warnings = true
|
44
44
|
end
|
@@ -60,7 +60,7 @@ module Steep
|
|
60
60
|
_, comments, _ = yield_self do
|
61
61
|
buffer = ::Parser::Source::Buffer.new(path.to_s)
|
62
62
|
buffer.source = source_code
|
63
|
-
parser = ::Parser::
|
63
|
+
parser = ::Parser::Ruby27.new
|
64
64
|
|
65
65
|
parser.tokenize(buffer)
|
66
66
|
end
|
@@ -79,6 +79,7 @@ module Steep
|
|
79
79
|
end
|
80
80
|
|
81
81
|
mapping = {}
|
82
|
+
|
82
83
|
construct_mapping(node: node, annotations: annotations, mapping: mapping)
|
83
84
|
|
84
85
|
annotations.each do |annot|
|
@@ -185,7 +186,7 @@ module Steep
|
|
185
186
|
construct_mapping(node: node.children[0], annotations: annotations, mapping: mapping, line_range: nil)
|
186
187
|
end
|
187
188
|
|
188
|
-
if node.
|
189
|
+
if node.children.last
|
189
190
|
else_node = node.children.last
|
190
191
|
else_start = node.loc.else.last_line
|
191
192
|
else_end = node.loc.end.line
|
@@ -42,9 +42,8 @@ module Steep
|
|
42
42
|
)
|
43
43
|
end
|
44
44
|
when RBS::Definition::Ancestor::Singleton
|
45
|
-
AST::Types::Name::
|
45
|
+
AST::Types::Name::Singleton.new(
|
46
46
|
name: name,
|
47
|
-
constructor: nil,
|
48
47
|
location: nil
|
49
48
|
)
|
50
49
|
end
|
@@ -78,9 +77,8 @@ module Steep
|
|
78
77
|
)
|
79
78
|
end
|
80
79
|
when RBS::Definition::Ancestor::Singleton
|
81
|
-
AST::Types::Name::
|
80
|
+
AST::Types::Name::Singleton.new(
|
82
81
|
name: name,
|
83
|
-
constructor: nil,
|
84
82
|
location: nil
|
85
83
|
)
|
86
84
|
end
|
@@ -180,14 +178,13 @@ module Steep
|
|
180
178
|
constraints: constraints
|
181
179
|
)
|
182
180
|
|
183
|
-
when relation.
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
)
|
181
|
+
when relation.super_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.super_type.name)
|
182
|
+
constraints.add(relation.super_type.name, sub_type: relation.sub_type)
|
183
|
+
success(constraints: constraints)
|
184
|
+
|
185
|
+
when relation.sub_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.sub_type.name)
|
186
|
+
constraints.add(relation.sub_type.name, super_type: relation.super_type)
|
187
|
+
success(constraints: constraints)
|
191
188
|
|
192
189
|
when relation.sub_type.is_a?(AST::Types::Union)
|
193
190
|
results = relation.sub_type.types.map do |sub_type|
|
@@ -241,14 +238,6 @@ module Steep
|
|
241
238
|
results.find(&:failure?)
|
242
239
|
end
|
243
240
|
|
244
|
-
when relation.super_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.super_type.name)
|
245
|
-
constraints.add(relation.super_type.name, sub_type: relation.sub_type)
|
246
|
-
success(constraints: constraints)
|
247
|
-
|
248
|
-
when relation.sub_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.sub_type.name)
|
249
|
-
constraints.add(relation.sub_type.name, super_type: relation.super_type)
|
250
|
-
success(constraints: constraints)
|
251
|
-
|
252
241
|
when relation.super_type.is_a?(AST::Types::Var) || relation.sub_type.is_a?(AST::Types::Var)
|
253
242
|
failure(error: Result::Failure::UnknownPairError.new(relation: relation),
|
254
243
|
trace: trace)
|
@@ -275,7 +264,7 @@ module Steep
|
|
275
264
|
possible_sub_types = case relation.sub_type
|
276
265
|
when AST::Types::Name::Instance
|
277
266
|
instance_super_types(relation.sub_type.name, args: relation.sub_type.args)
|
278
|
-
when AST::Types::Name::
|
267
|
+
when AST::Types::Name::Singleton
|
279
268
|
singleton_super_types(relation.sub_type.name)
|
280
269
|
else
|
281
270
|
[]
|
@@ -311,10 +300,9 @@ module Steep
|
|
311
300
|
when relation.sub_type.is_a?(AST::Types::Tuple) && relation.super_type.is_a?(AST::Types::Tuple)
|
312
301
|
if relation.sub_type.types.size >= relation.super_type.types.size
|
313
302
|
pairs = relation.sub_type.types.take(relation.super_type.types.size).zip(relation.super_type.types)
|
314
|
-
results = pairs.
|
303
|
+
results = pairs.map do |t1, t2|
|
315
304
|
relation = Relation.new(sub_type: t1, super_type: t2)
|
316
|
-
|
317
|
-
check(relation.flip, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)]
|
305
|
+
check(relation, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)
|
318
306
|
end
|
319
307
|
|
320
308
|
if results.all?(&:success?)
|
@@ -327,16 +315,17 @@ module Steep
|
|
327
315
|
trace: trace)
|
328
316
|
end
|
329
317
|
|
330
|
-
when relation.sub_type.is_a?(AST::Types::Tuple) && relation.super_type
|
331
|
-
|
332
|
-
|
318
|
+
when relation.sub_type.is_a?(AST::Types::Tuple) && AST::Builtin::Array.instance_type?(relation.super_type)
|
319
|
+
tuple_element_type = AST::Types::Union.build(
|
320
|
+
types: relation.sub_type.types,
|
321
|
+
location: relation.sub_type.location
|
322
|
+
)
|
333
323
|
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
constraints: constraints)
|
324
|
+
check(Relation.new(sub_type: tuple_element_type, super_type: relation.super_type.args[0]),
|
325
|
+
self_type: self_type,
|
326
|
+
assumption: assumption,
|
327
|
+
trace: trace,
|
328
|
+
constraints: constraints)
|
340
329
|
|
341
330
|
when relation.sub_type.is_a?(AST::Types::Record) && relation.super_type.is_a?(AST::Types::Record)
|
342
331
|
if Set.new(relation.sub_type.elements.keys).superset?(Set.new(relation.super_type.elements.keys))
|
@@ -386,6 +375,15 @@ module Steep
|
|
386
375
|
when relation.sub_type.is_a?(AST::Types::Nil) && AST::Builtin::NilClass.instance_type?(relation.super_type)
|
387
376
|
success(constraints: constraints)
|
388
377
|
|
378
|
+
when relation.sub_type.is_a?(AST::Types::Literal)
|
379
|
+
check(
|
380
|
+
Relation.new(sub_type: relation.sub_type.back_type, super_type: relation.super_type),
|
381
|
+
self_type: self_type,
|
382
|
+
assumption: assumption,
|
383
|
+
trace: trace,
|
384
|
+
constraints: constraints
|
385
|
+
)
|
386
|
+
|
389
387
|
else
|
390
388
|
failure(error: Result::Failure::UnknownPairError.new(relation: relation),
|
391
389
|
trace: trace)
|
@@ -399,7 +397,7 @@ module Steep
|
|
399
397
|
case type
|
400
398
|
when AST::Types::Name::Instance
|
401
399
|
factory.definition_builder.build_instance(type_name)
|
402
|
-
when AST::Types::Name::
|
400
|
+
when AST::Types::Name::Singleton
|
403
401
|
factory.definition_builder.build_singleton(type_name)
|
404
402
|
when AST::Types::Name::Interface
|
405
403
|
factory.definition_builder.build_interface(type_name)
|
@@ -484,11 +482,7 @@ module Steep
|
|
484
482
|
if sub_type.name == super_type.name && sub_type.args.size == super_type.args.size
|
485
483
|
sub_type.args.zip(super_type.args)
|
486
484
|
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)
|
485
|
+
when sub_type.is_a?(AST::Types::Name::Singleton) && super_type.is_a?(AST::Types::Name::Singleton)
|
492
486
|
if sub_type.name == super_type.name
|
493
487
|
[]
|
494
488
|
end
|
@@ -535,29 +529,24 @@ module Steep
|
|
535
529
|
|
536
530
|
def check_method(name, sub_method, super_method, self_type:, assumption:, trace:, constraints:)
|
537
531
|
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
|
532
|
+
super_method.method_types.map do |super_type|
|
533
|
+
sub_method.method_types.map do |sub_type|
|
534
|
+
check_generic_method_type name,
|
535
|
+
sub_type,
|
536
|
+
super_type,
|
537
|
+
self_type: self_type,
|
538
|
+
assumption: assumption,
|
539
|
+
trace: trace,
|
540
|
+
constraints: constraints
|
552
541
|
end.yield_self do |results|
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
542
|
+
results.find(&:success?) || results[0]
|
543
|
+
end
|
544
|
+
end.yield_self do |results|
|
545
|
+
if results.all?(&:success?)
|
546
|
+
success constraints: constraints
|
547
|
+
else
|
548
|
+
results.select(&:failure?).last
|
558
549
|
end
|
559
|
-
else
|
560
|
-
raise "aaaaaaaaaaaaaa"
|
561
550
|
end
|
562
551
|
end
|
563
552
|
end
|
@@ -113,6 +113,7 @@ module Steep
|
|
113
113
|
end
|
114
114
|
|
115
115
|
def check_relation(sub_type:, super_type:, constraints: Subtyping::Constraints.empty)
|
116
|
+
Steep.logger.debug { "check_relation: self:#{self_type} |- #{sub_type} <: #{super_type}" }
|
116
117
|
checker.check(Subtyping::Relation.new(sub_type: sub_type, super_type: super_type), self_type: self_type, constraints: constraints)
|
117
118
|
end
|
118
119
|
|
@@ -286,7 +287,6 @@ module Steep
|
|
286
287
|
|
287
288
|
instance_type = AST::Types::Intersection.build(
|
288
289
|
types: [
|
289
|
-
AST::Types::Name::Instance.new(name: module_name, args: module_args),
|
290
290
|
AST::Builtin::Object.instance_type,
|
291
291
|
*module_entry.self_types.map {|module_self|
|
292
292
|
type = case
|
@@ -304,11 +304,12 @@ module Steep
|
|
304
304
|
)
|
305
305
|
end
|
306
306
|
checker.factory.type(type)
|
307
|
-
}
|
307
|
+
},
|
308
|
+
AST::Types::Name::Instance.new(name: module_name, args: module_args)
|
308
309
|
].compact
|
309
310
|
)
|
310
311
|
|
311
|
-
module_type = AST::Types::Name::
|
312
|
+
module_type = AST::Types::Name::Singleton.new(name: module_name)
|
312
313
|
end
|
313
314
|
|
314
315
|
if annots.instance_type
|
@@ -379,7 +380,7 @@ module Steep
|
|
379
380
|
module_def = checker.factory.definition_builder.build_singleton(type_name_)
|
380
381
|
|
381
382
|
instance_type = AST::Types::Name::Instance.new(name: class_name, args: class_args)
|
382
|
-
module_type = AST::Types::Name::
|
383
|
+
module_type = AST::Types::Name::Singleton.new(name: class_name)
|
383
384
|
end
|
384
385
|
|
385
386
|
if annots.instance_type
|
@@ -443,18 +444,26 @@ module Steep
|
|
443
444
|
end
|
444
445
|
|
445
446
|
module_type = case instance_type
|
446
|
-
when AST::Types::Name::
|
447
|
-
|
448
|
-
|
449
|
-
|
447
|
+
when AST::Types::Name::Singleton
|
448
|
+
type_name = checker.factory.type_name_1(instance_type.name)
|
449
|
+
|
450
|
+
case checker.factory.env.class_decls[type_name]
|
451
|
+
when RBS::Environment::ModuleEntry
|
452
|
+
AST::Builtin::Module.instance_type
|
453
|
+
when RBS::Environment::ClassEntry
|
454
|
+
AST::Builtin::Class.instance_type
|
455
|
+
else
|
456
|
+
raise
|
457
|
+
end
|
458
|
+
|
450
459
|
when AST::Types::Name::Instance
|
451
|
-
instance_type.
|
460
|
+
instance_type.to_module
|
452
461
|
else
|
453
|
-
|
462
|
+
return
|
454
463
|
end
|
455
464
|
|
456
465
|
instance_definition = case instance_type
|
457
|
-
when AST::Types::Name::
|
466
|
+
when AST::Types::Name::Singleton
|
458
467
|
type_name = checker.factory.type_name_1(instance_type.name)
|
459
468
|
checker.factory.definition_builder.build_singleton(type_name)
|
460
469
|
when AST::Types::Name::Instance
|
@@ -463,7 +472,7 @@ module Steep
|
|
463
472
|
end
|
464
473
|
|
465
474
|
module_definition = case module_type
|
466
|
-
when AST::Types::Name::
|
475
|
+
when AST::Types::Name::Singleton
|
467
476
|
type_name = checker.factory.type_name_1(instance_type.name)
|
468
477
|
checker.factory.definition_builder.build_singleton(type_name)
|
469
478
|
else
|
@@ -638,7 +647,11 @@ module Steep
|
|
638
647
|
when :__skip__
|
639
648
|
add_typing(node, type: AST::Builtin.any_type)
|
640
649
|
else
|
641
|
-
|
650
|
+
if !hint || hint.is_a?(AST::Types::Void)
|
651
|
+
hint = context.lvar_env.declared_types[name]&.type
|
652
|
+
end
|
653
|
+
|
654
|
+
rhs_result = synthesize(rhs, hint: hint)
|
642
655
|
|
643
656
|
constr = rhs_result.constr.update_lvar_env do |lvar_env|
|
644
657
|
lvar_env.assign(name, node: node, type: rhs_result.type) do |declared_type, actual_type, result|
|
@@ -682,8 +695,8 @@ module Steep
|
|
682
695
|
yield_self do
|
683
696
|
if self_class?(node)
|
684
697
|
module_type = expand_alias(module_context.module_type)
|
685
|
-
type = if module_type.is_a?(AST::Types::Name::
|
686
|
-
AST::Types::Name::
|
698
|
+
type = if module_type.is_a?(AST::Types::Name::Singleton)
|
699
|
+
AST::Types::Name::Singleton.new(name: module_type.name)
|
687
700
|
else
|
688
701
|
module_type
|
689
702
|
end
|
@@ -698,8 +711,8 @@ module Steep
|
|
698
711
|
yield_self do
|
699
712
|
pair = if self_class?(node)
|
700
713
|
module_type = expand_alias(module_context.module_type)
|
701
|
-
type = if module_type.is_a?(AST::Types::Name::
|
702
|
-
AST::Types::Name::
|
714
|
+
type = if module_type.is_a?(AST::Types::Name::Singleton)
|
715
|
+
AST::Types::Name::Singleton.new(name: module_type.name)
|
703
716
|
else
|
704
717
|
module_type
|
705
718
|
end
|
@@ -743,6 +756,23 @@ module Steep
|
|
743
756
|
|
744
757
|
constr.add_typing(node, type: type)
|
745
758
|
|
759
|
+
when :cvasgn
|
760
|
+
var_node = lhs.updated(:cvar)
|
761
|
+
send_node = rhs.updated(:send, [var_node, op, rhs])
|
762
|
+
new_node = node.updated(:cvasgn, [lhs.children[0], send_node])
|
763
|
+
|
764
|
+
type, constr = synthesize(new_node, hint: hint)
|
765
|
+
|
766
|
+
constr.add_typing(node, type: type)
|
767
|
+
|
768
|
+
when :send
|
769
|
+
new_rhs = rhs.updated(:send, [lhs, node.children[1], node.children[2]])
|
770
|
+
new_node = lhs.updated(:send, [lhs.children[0], :"#{lhs.children[1]}=", *lhs.children.drop(2), new_rhs])
|
771
|
+
|
772
|
+
type, constr = synthesize(new_node, hint: hint)
|
773
|
+
|
774
|
+
constr.add_typing(node, type: type)
|
775
|
+
|
746
776
|
else
|
747
777
|
Steep.logger.error("Unexpected op_asgn lhs: #{lhs.type}")
|
748
778
|
|
@@ -759,11 +789,10 @@ module Steep
|
|
759
789
|
synthesize(child)
|
760
790
|
end
|
761
791
|
|
762
|
-
super_method = Interface::Interface::
|
763
|
-
method_context.super_method.method_types.map {|method_type|
|
792
|
+
super_method = Interface::Interface::Entry.new(
|
793
|
+
method_types: method_context.super_method.method_types.map {|method_type|
|
764
794
|
checker.factory.method_type(method_type, self_type: self_type)
|
765
|
-
}
|
766
|
-
incompatible: false
|
795
|
+
}
|
767
796
|
)
|
768
797
|
args = TypeInference::SendArgs.from_nodes(node.children.dup)
|
769
798
|
|
@@ -810,7 +839,7 @@ module Steep
|
|
810
839
|
new.typing.add_context_for_body(node, context: new.context)
|
811
840
|
|
812
841
|
each_child_node(args_node) do |arg|
|
813
|
-
new.synthesize(arg)
|
842
|
+
_, new = new.synthesize(arg)
|
814
843
|
end
|
815
844
|
|
816
845
|
body_pair = if body_node
|
@@ -861,7 +890,7 @@ module Steep
|
|
861
890
|
when AST::Types::Name::Instance
|
862
891
|
name = checker.factory.type_name_1(self_type.name)
|
863
892
|
checker.factory.definition_builder.build_singleton(name)
|
864
|
-
when AST::Types::Name::
|
893
|
+
when AST::Types::Name::Singleton
|
865
894
|
name = checker.factory.type_name_1(self_type.name)
|
866
895
|
checker.factory.definition_builder.build_singleton(name)
|
867
896
|
end
|
@@ -998,11 +1027,17 @@ module Steep
|
|
998
1027
|
yield_self do
|
999
1028
|
var = node.children[0]
|
1000
1029
|
type = context.lvar_env[var.name]
|
1001
|
-
|
1030
|
+
|
1031
|
+
if type
|
1032
|
+
add_typing(node, type: type)
|
1033
|
+
else
|
1002
1034
|
type = AST::Builtin.any_type
|
1003
|
-
|
1035
|
+
if context&.method_context&.method_type
|
1036
|
+
Steep.logger.error { "Unknown arg type: #{node}" }
|
1037
|
+
end
|
1038
|
+
|
1039
|
+
lvasgn(node, type)
|
1004
1040
|
end
|
1005
|
-
add_typing(node, type: type)
|
1006
1041
|
end
|
1007
1042
|
|
1008
1043
|
when :optarg, :kwoptarg
|
@@ -1010,12 +1045,13 @@ module Steep
|
|
1010
1045
|
var = node.children[0]
|
1011
1046
|
rhs = node.children[1]
|
1012
1047
|
|
1013
|
-
|
1048
|
+
var_type = context.lvar_env[var.name]
|
1049
|
+
node_type, constr = synthesize(rhs, hint: var_type)
|
1014
1050
|
|
1015
|
-
|
1051
|
+
type = AST::Types::Union.build(types: [var_type, node_type])
|
1016
1052
|
|
1017
1053
|
constr_ = constr.update_lvar_env do |env|
|
1018
|
-
env.assign(var.name, node: node, type:
|
1054
|
+
env.assign(var.name, node: node, type: type) do |declared_type, type, result|
|
1019
1055
|
typing.add_error(
|
1020
1056
|
Errors::IncompatibleAssignment.new(node: node,
|
1021
1057
|
lhs_type: declared_type,
|
@@ -1025,7 +1061,7 @@ module Steep
|
|
1025
1061
|
end
|
1026
1062
|
end
|
1027
1063
|
|
1028
|
-
add_typing(node, type:
|
1064
|
+
add_typing(node, type: type, constr: constr_)
|
1029
1065
|
end
|
1030
1066
|
|
1031
1067
|
when :restarg
|
@@ -1033,7 +1069,9 @@ module Steep
|
|
1033
1069
|
var = node.children[0]
|
1034
1070
|
type = context.lvar_env[var.name]
|
1035
1071
|
unless type
|
1036
|
-
|
1072
|
+
if context&.method_context&.method_type
|
1073
|
+
Steep.logger.error { "Unknown variable: #{node}" }
|
1074
|
+
end
|
1037
1075
|
typing.add_error Errors::FallbackAny.new(node: node)
|
1038
1076
|
type = AST::Builtin::Array.instance_type(AST::Builtin.any_type)
|
1039
1077
|
end
|
@@ -1046,7 +1084,9 @@ module Steep
|
|
1046
1084
|
var = node.children[0]
|
1047
1085
|
type = context.lvar_env[var.name]
|
1048
1086
|
unless type
|
1049
|
-
|
1087
|
+
if context&.method_context&.method_type
|
1088
|
+
Steep.logger.error { "Unknown variable: #{node}" }
|
1089
|
+
end
|
1050
1090
|
typing.add_error Errors::FallbackAny.new(node: node)
|
1051
1091
|
type = AST::Builtin::Hash.instance_type(AST::Builtin::Symbol.instance_type, AST::Builtin.any_type)
|
1052
1092
|
end
|
@@ -1062,7 +1102,7 @@ module Steep
|
|
1062
1102
|
|
1063
1103
|
when :int
|
1064
1104
|
yield_self do
|
1065
|
-
literal_type =
|
1105
|
+
literal_type = test_literal_type(node.children[0], hint)
|
1066
1106
|
|
1067
1107
|
if literal_type
|
1068
1108
|
add_typing(node, type: literal_type)
|
@@ -1073,7 +1113,7 @@ module Steep
|
|
1073
1113
|
|
1074
1114
|
when :sym
|
1075
1115
|
yield_self do
|
1076
|
-
literal_type =
|
1116
|
+
literal_type = test_literal_type(node.children[0], hint)
|
1077
1117
|
|
1078
1118
|
if literal_type
|
1079
1119
|
add_typing(node, type: literal_type)
|
@@ -1084,7 +1124,7 @@ module Steep
|
|
1084
1124
|
|
1085
1125
|
when :str
|
1086
1126
|
yield_self do
|
1087
|
-
literal_type =
|
1127
|
+
literal_type = test_literal_type(node.children[0], hint)
|
1088
1128
|
|
1089
1129
|
if literal_type
|
1090
1130
|
add_typing(node, type: literal_type)
|
@@ -1201,6 +1241,17 @@ module Steep
|
|
1201
1241
|
type, constr = synthesize(node.children[0])
|
1202
1242
|
constructor = constr.for_sclass(node, type)
|
1203
1243
|
|
1244
|
+
unless constructor
|
1245
|
+
typing.add_error(
|
1246
|
+
Errors::UnsupportedSyntax.new(
|
1247
|
+
node: node,
|
1248
|
+
message: "sclass receiver must be instance type or singleton type, but type given `#{type}`"
|
1249
|
+
)
|
1250
|
+
)
|
1251
|
+
constr.add_typing(node, type: AST::Builtin.nil_type)
|
1252
|
+
return
|
1253
|
+
end
|
1254
|
+
|
1204
1255
|
constructor.typing.add_context_for_node(node, context: constructor.context)
|
1205
1256
|
constructor.typing.add_context_for_body(node, context: constructor.context)
|
1206
1257
|
|
@@ -1212,7 +1263,7 @@ module Steep
|
|
1212
1263
|
end
|
1213
1264
|
end
|
1214
1265
|
|
1215
|
-
add_typing(node, type: AST::Builtin.nil_type)
|
1266
|
+
constr.add_typing(node, type: AST::Builtin.nil_type)
|
1216
1267
|
end
|
1217
1268
|
|
1218
1269
|
when :self
|
@@ -1300,69 +1351,45 @@ module Steep
|
|
1300
1351
|
when :array
|
1301
1352
|
yield_self do
|
1302
1353
|
if node.children.empty?
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1309
|
-
end
|
1310
|
-
end
|
1311
|
-
|
1312
|
-
add_typing(node, type: array_type || AST::Builtin::Array.instance_type(AST::Builtin.any_type))
|
1313
|
-
else
|
1314
|
-
is_tuple = nil
|
1315
|
-
|
1316
|
-
expand_alias(hint) do |hint|
|
1317
|
-
is_tuple = hint.is_a?(AST::Types::Tuple)
|
1318
|
-
is_tuple &&= node.children.all? {|child| child.type != :splat}
|
1319
|
-
is_tuple &&= node.children.size >= hint.types.size
|
1320
|
-
is_tuple &&= hint.types.map.with_index do |child_type, index|
|
1321
|
-
child_node = node.children[index]
|
1322
|
-
[synthesize(child_node, hint: child_type).type, child_type]
|
1323
|
-
end.all? do |node_type, hint_type|
|
1324
|
-
result = check_relation(sub_type: node_type, super_type: hint_type)
|
1325
|
-
result.success?
|
1354
|
+
if hint
|
1355
|
+
array = AST::Builtin::Array.instance_type(AST::Builtin.any_type)
|
1356
|
+
if check_relation(sub_type: array, super_type: hint).success?
|
1357
|
+
add_typing node, type: hint
|
1358
|
+
else
|
1359
|
+
add_typing node, type: array
|
1326
1360
|
end
|
1327
|
-
end
|
1328
|
-
|
1329
|
-
if is_tuple
|
1330
|
-
array_type = hint
|
1331
1361
|
else
|
1332
|
-
|
1333
|
-
|
1362
|
+
typing.add_error Errors::FallbackAny.new(node: node)
|
1363
|
+
add_typing node, type: AST::Builtin::Array.instance_type(AST::Builtin.any_type)
|
1364
|
+
end
|
1365
|
+
else
|
1366
|
+
node_range = node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
|
1367
|
+
|
1368
|
+
if hint && !(tuples = select_flatten_types(hint) {|type| type.is_a?(AST::Types::Tuple) }).empty?
|
1369
|
+
tuples.each do |tuple|
|
1370
|
+
typing.new_child(node_range) do |child_typing|
|
1371
|
+
pair = with_new_typing(child_typing).try_tuple_type(node, tuple)
|
1372
|
+
if pair && pair.constr.check_relation(sub_type: pair.type, super_type: hint).success?
|
1373
|
+
child_typing.save!
|
1374
|
+
return pair.with(constr: pair.constr.with_new_typing(typing))
|
1375
|
+
end
|
1376
|
+
end
|
1334
1377
|
end
|
1378
|
+
end
|
1335
1379
|
|
1336
|
-
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
ty.types
|
1344
|
-
else
|
1345
|
-
[ty]
|
1346
|
-
end
|
1347
|
-
end
|
1348
|
-
end.map do |type|
|
1349
|
-
case
|
1350
|
-
when AST::Builtin::Array.instance_type?(type)
|
1351
|
-
type.args.first
|
1352
|
-
when AST::Builtin::Range.instance_type?(type)
|
1353
|
-
type.args.first
|
1354
|
-
else
|
1355
|
-
type
|
1356
|
-
end
|
1380
|
+
if hint && !(arrays = select_flatten_types(hint) {|type| AST::Builtin::Array.instance_type?(type) }).empty?
|
1381
|
+
arrays.each do |array|
|
1382
|
+
typing.new_child(node_range) do |child_typing|
|
1383
|
+
pair = with_new_typing(child_typing).try_array_type(node, array)
|
1384
|
+
if pair.constr.check_relation(sub_type: pair.type, super_type: hint).success?
|
1385
|
+
child_typing.save!
|
1386
|
+
return pair.with(constr: pair.constr.with_new_typing(typing))
|
1357
1387
|
end
|
1358
|
-
else
|
1359
|
-
[select_super_type(synthesize(e, hint: element_hint).type, element_hint)]
|
1360
1388
|
end
|
1361
1389
|
end
|
1362
|
-
array_type = AST::Builtin::Array.instance_type(AST::Types::Union.build(types: element_types))
|
1363
1390
|
end
|
1364
1391
|
|
1365
|
-
|
1392
|
+
try_array_type(node, nil)
|
1366
1393
|
end
|
1367
1394
|
end
|
1368
1395
|
|
@@ -1505,38 +1532,53 @@ module Steep
|
|
1505
1532
|
test_types << expand_alias(type)
|
1506
1533
|
end
|
1507
1534
|
|
1508
|
-
if
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1512
|
-
var_type.is_a?(AST::Types::Name::Base) && var_type.name == test_type.name
|
1513
|
-
end
|
1514
|
-
if filtered_types.empty?
|
1515
|
-
to_instance_type(test_type)
|
1516
|
-
else
|
1517
|
-
filtered_types
|
1518
|
-
end
|
1535
|
+
if var_names && var_types && test_types.all? {|ty| ty.is_a?(AST::Types::Name::Singleton) }
|
1536
|
+
var_types_in_body = test_types.flat_map do |test_type|
|
1537
|
+
filtered_types = var_types.select do |var_type|
|
1538
|
+
var_type.is_a?(AST::Types::Name::Base) && var_type.name == test_type.name
|
1519
1539
|
end
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
end
|
1540
|
+
if filtered_types.empty?
|
1541
|
+
to_instance_type(test_type)
|
1542
|
+
else
|
1543
|
+
filtered_types
|
1525
1544
|
end
|
1545
|
+
end
|
1526
1546
|
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1547
|
+
var_types.reject! do |type|
|
1548
|
+
var_types_in_body.any? do |test_type|
|
1549
|
+
type.is_a?(AST::Types::Name::Base) && test_type.name == type.name
|
1530
1550
|
end
|
1551
|
+
end
|
1552
|
+
|
1553
|
+
var_type_in_body = union_type(*var_types_in_body)
|
1554
|
+
type_case_override = var_names.each.with_object({}) do |var_name, hash|
|
1555
|
+
hash[var_name] = var_type_in_body
|
1556
|
+
end
|
1531
1557
|
|
1558
|
+
if body
|
1532
1559
|
branch_pairs << clause_constr
|
1533
1560
|
.for_branch(body, type_case_override: type_case_override)
|
1534
1561
|
.synthesize(body, hint: hint)
|
1535
1562
|
else
|
1536
|
-
branch_pairs <<
|
1563
|
+
branch_pairs << Pair.new(type: AST::Builtin.nil_type, constr: clause_constr)
|
1537
1564
|
end
|
1538
1565
|
else
|
1539
|
-
|
1566
|
+
logic = TypeInference::Logic.new(subtyping: checker)
|
1567
|
+
|
1568
|
+
truthys, falseys = logic.nodes(node: ::AST::Node.new(:begin, tests))
|
1569
|
+
truthy_env, _ = logic.environments(truthy_vars: truthys.vars,
|
1570
|
+
falsey_vars: falseys.vars,
|
1571
|
+
lvar_env: clause_constr.context.lvar_env)
|
1572
|
+
|
1573
|
+
if body
|
1574
|
+
branch_pairs << constr
|
1575
|
+
.update_lvar_env { truthy_env }
|
1576
|
+
.for_branch(body)
|
1577
|
+
.tap {|constr| typing.add_context_for_node(body, context: constr.context) }
|
1578
|
+
.synthesize(body, hint: hint)
|
1579
|
+
else
|
1580
|
+
branch_pairs << Pair.new(type: AST::Builtin.nil_type, constr: clause_constr)
|
1581
|
+
end
|
1540
1582
|
end
|
1541
1583
|
end
|
1542
1584
|
|
@@ -1616,7 +1658,7 @@ module Steep
|
|
1616
1658
|
instance_types = exn_types.map do |type|
|
1617
1659
|
type = expand_alias(type)
|
1618
1660
|
case
|
1619
|
-
when type.is_a?(AST::Types::Name::
|
1661
|
+
when type.is_a?(AST::Types::Name::Singleton)
|
1620
1662
|
to_instance_type(type)
|
1621
1663
|
else
|
1622
1664
|
AST::Builtin.any_type
|
@@ -1671,6 +1713,49 @@ module Steep
|
|
1671
1713
|
when :masgn
|
1672
1714
|
type_masgn(node)
|
1673
1715
|
|
1716
|
+
when :for
|
1717
|
+
yield_self do
|
1718
|
+
asgn, collection, body = node.children
|
1719
|
+
|
1720
|
+
collection_type, constr = synthesize(collection)
|
1721
|
+
collection_type = expand_self(collection_type)
|
1722
|
+
|
1723
|
+
var_type = case collection_type
|
1724
|
+
when AST::Types::Any
|
1725
|
+
AST::Types::Any.new
|
1726
|
+
else
|
1727
|
+
each = checker.factory.interface(collection_type, private: true).methods[:each]
|
1728
|
+
method_type = (each&.method_types || []).find {|type| type.block && type.block.type.params.first_param }
|
1729
|
+
method_type&.yield_self do |method_type|
|
1730
|
+
method_type.block.type.params.first_param&.type
|
1731
|
+
end
|
1732
|
+
end
|
1733
|
+
|
1734
|
+
if var_type
|
1735
|
+
if body
|
1736
|
+
body_constr = constr.with_updated_context(
|
1737
|
+
lvar_env: constr.context.lvar_env.assign(asgn.children[0].name, node: asgn, type: var_type)
|
1738
|
+
)
|
1739
|
+
|
1740
|
+
typing.add_context_for_body(node, context: body_constr.context)
|
1741
|
+
_, _, body_context = body_constr.synthesize(body)
|
1742
|
+
|
1743
|
+
constr = constr.update_lvar_env {|env| env.join(constr.context.lvar_env, body_context.lvar_env) }
|
1744
|
+
else
|
1745
|
+
constr = self
|
1746
|
+
end
|
1747
|
+
|
1748
|
+
add_typing(node, type: collection_type, constr: constr)
|
1749
|
+
else
|
1750
|
+
fallback_to_any(node) do
|
1751
|
+
Errors::NoMethod.new(
|
1752
|
+
node: node,
|
1753
|
+
method: :each,
|
1754
|
+
type: collection_type
|
1755
|
+
)
|
1756
|
+
end
|
1757
|
+
end
|
1758
|
+
end
|
1674
1759
|
when :while, :until
|
1675
1760
|
yield_self do
|
1676
1761
|
cond, body = node.children
|
@@ -1732,9 +1817,22 @@ module Steep
|
|
1732
1817
|
end
|
1733
1818
|
|
1734
1819
|
when :irange, :erange
|
1735
|
-
|
1736
|
-
|
1737
|
-
|
1820
|
+
begin_node, end_node = node.children
|
1821
|
+
|
1822
|
+
constr = self
|
1823
|
+
begin_type, constr = if begin_node
|
1824
|
+
constr.synthesize(begin_node)
|
1825
|
+
else
|
1826
|
+
[AST::Builtin.nil_type, constr]
|
1827
|
+
end
|
1828
|
+
end_type, constr = if end_node
|
1829
|
+
constr.synthesize(end_node)
|
1830
|
+
else
|
1831
|
+
[AST::Builtin.nil_type, constr]
|
1832
|
+
end
|
1833
|
+
|
1834
|
+
type = AST::Builtin::Range.instance_type(union_type(begin_type, end_type))
|
1835
|
+
add_typing(node, type: type, constr: constr)
|
1738
1836
|
|
1739
1837
|
when :regexp
|
1740
1838
|
each_child_node(node) do |child|
|
@@ -1752,9 +1850,36 @@ module Steep
|
|
1752
1850
|
|
1753
1851
|
when :or_asgn, :and_asgn
|
1754
1852
|
yield_self do
|
1755
|
-
|
1756
|
-
|
1757
|
-
|
1853
|
+
asgn, rhs = node.children
|
1854
|
+
|
1855
|
+
case asgn.type
|
1856
|
+
when :lvasgn
|
1857
|
+
type, constr = synthesize(rhs, hint: hint)
|
1858
|
+
constr.lvasgn(asgn, type)
|
1859
|
+
when :ivasgn
|
1860
|
+
type, constr = synthesize(rhs, hint: hint)
|
1861
|
+
constr.ivasgn(asgn, type)
|
1862
|
+
when :send
|
1863
|
+
rhs_ = node.updated(:send,
|
1864
|
+
[
|
1865
|
+
asgn.children[0],
|
1866
|
+
:"#{asgn.children[1]}=",
|
1867
|
+
asgn.children[2],
|
1868
|
+
rhs
|
1869
|
+
])
|
1870
|
+
node_type = case node.type
|
1871
|
+
when :or_asgn
|
1872
|
+
:or
|
1873
|
+
when :and_asgn
|
1874
|
+
:and
|
1875
|
+
end
|
1876
|
+
node_ = node.updated(node_type, [asgn, rhs_])
|
1877
|
+
|
1878
|
+
synthesize(node_, hint: hint)
|
1879
|
+
else
|
1880
|
+
Steep.logger.error { "#{node.type} with #{asgn.type} lhs is not supported"}
|
1881
|
+
fallback_to_any(node)
|
1882
|
+
end
|
1758
1883
|
end
|
1759
1884
|
|
1760
1885
|
when :defined?
|
@@ -1801,8 +1926,8 @@ module Steep
|
|
1801
1926
|
param_type = hint.params.required[0]
|
1802
1927
|
interface = checker.factory.interface(param_type, private: true)
|
1803
1928
|
method = interface.methods[value.children[0]]
|
1804
|
-
if method
|
1805
|
-
return_types = method.
|
1929
|
+
if method
|
1930
|
+
return_types = method.method_types.select {|method_type|
|
1806
1931
|
method_type.params.each_type.count == 0
|
1807
1932
|
}.map(&:return_type)
|
1808
1933
|
|
@@ -1830,9 +1955,50 @@ module Steep
|
|
1830
1955
|
add_typing node, type: AST::Builtin.any_type
|
1831
1956
|
end
|
1832
1957
|
|
1833
|
-
when :
|
1958
|
+
when :cvasgn
|
1959
|
+
name, rhs = node.children
|
1960
|
+
|
1961
|
+
type, constr = synthesize(rhs, hint: hint)
|
1962
|
+
|
1963
|
+
var_type = if module_context&.class_variables
|
1964
|
+
module_context.class_variables[name]&.yield_self {|ty| checker.factory.type(ty) }
|
1965
|
+
end
|
1966
|
+
|
1967
|
+
if var_type
|
1968
|
+
result = constr.check_relation(sub_type: type, super_type: var_type)
|
1969
|
+
|
1970
|
+
if result.success?
|
1971
|
+
add_typing node, type: type, constr: constr
|
1972
|
+
else
|
1973
|
+
fallback_to_any node do
|
1974
|
+
Errors::IncompatibleAssignment.new(node: node,
|
1975
|
+
lhs_type: var_type,
|
1976
|
+
rhs_type: type,
|
1977
|
+
result: result)
|
1978
|
+
end
|
1979
|
+
end
|
1980
|
+
else
|
1981
|
+
fallback_to_any(node)
|
1982
|
+
end
|
1983
|
+
|
1984
|
+
when :cvar
|
1985
|
+
name = node.children[0]
|
1986
|
+
var_type = if module_context&.class_variables
|
1987
|
+
module_context.class_variables[name]&.yield_self {|ty| checker.factory.type(ty) }
|
1988
|
+
end
|
1989
|
+
|
1990
|
+
if var_type
|
1991
|
+
add_typing node, type: var_type
|
1992
|
+
else
|
1993
|
+
fallback_to_any node
|
1994
|
+
end
|
1995
|
+
|
1996
|
+
when :alias
|
1997
|
+
add_typing node, type: AST::Builtin.nil_type
|
1998
|
+
|
1999
|
+
when :splat
|
1834
2000
|
yield_self do
|
1835
|
-
Steep.logger.
|
2001
|
+
Steep.logger.warn { "Unsupported node #{node.type} (#{node.location.expression.source_buffer.name}:#{node.location.expression.line})" }
|
1836
2002
|
|
1837
2003
|
each_child_node node do |child|
|
1838
2004
|
synthesize(child)
|
@@ -1882,136 +2048,202 @@ module Steep
|
|
1882
2048
|
add_typing(node, type: ivar_type)
|
1883
2049
|
end
|
1884
2050
|
|
2051
|
+
def masgn_lhs?(lhs)
|
2052
|
+
lhs.children.all? do |a|
|
2053
|
+
asgn_type = if a.type == :splat
|
2054
|
+
a.children[0].type
|
2055
|
+
else
|
2056
|
+
a.type
|
2057
|
+
end
|
2058
|
+
asgn_type == :lvasgn || asgn_type == :ivasgn
|
2059
|
+
end
|
2060
|
+
end
|
2061
|
+
|
2062
|
+
def lvasgn(node, type)
|
2063
|
+
name = node.children[0].name
|
2064
|
+
env = context.lvar_env.assign(name, node: node, type: type) do |declared_type, type, result|
|
2065
|
+
typing.add_error(
|
2066
|
+
Errors::IncompatibleAssignment.new(node: node,
|
2067
|
+
lhs_type: declared_type,
|
2068
|
+
rhs_type: type,
|
2069
|
+
result: result)
|
2070
|
+
)
|
2071
|
+
end
|
2072
|
+
|
2073
|
+
add_typing(node, type: type, constr: with_updated_context(lvar_env: env))
|
2074
|
+
end
|
2075
|
+
|
2076
|
+
def ivasgn(node, type)
|
2077
|
+
ivar = node.children[0]
|
2078
|
+
|
2079
|
+
type_env.assign(ivar: ivar, type: type, self_type: self_type) do |error|
|
2080
|
+
case error
|
2081
|
+
when Subtyping::Result::Failure
|
2082
|
+
var_type = type_env.get(ivar: ivar)
|
2083
|
+
typing.add_error(Errors::IncompatibleAssignment.new(node: node,
|
2084
|
+
lhs_type: var_type,
|
2085
|
+
rhs_type: type,
|
2086
|
+
result: error))
|
2087
|
+
when nil
|
2088
|
+
fallback_to_any node
|
2089
|
+
end
|
2090
|
+
end
|
2091
|
+
|
2092
|
+
add_typing(node, type: type)
|
2093
|
+
end
|
2094
|
+
|
1885
2095
|
def type_masgn(node)
|
1886
2096
|
lhs, rhs = node.children
|
1887
2097
|
rhs_pair = synthesize(rhs)
|
1888
|
-
rhs_type =
|
2098
|
+
rhs_type = deep_expand_alias(rhs_pair.type)
|
1889
2099
|
|
1890
2100
|
constr = rhs_pair.constr
|
1891
2101
|
|
1892
|
-
|
1893
|
-
|
1894
|
-
|
1895
|
-
|
2102
|
+
unless masgn_lhs?(lhs)
|
2103
|
+
Steep.logger.error("Unsupported masgn lhs node: only lvasgn, ivasgn, and splat are supported")
|
2104
|
+
_, constr = constr.fallback_to_any(lhs)
|
2105
|
+
return add_typing(node, type: rhs_type, constr: constr)
|
2106
|
+
end
|
1896
2107
|
|
1897
|
-
|
1898
|
-
|
1899
|
-
|
1900
|
-
|
1901
|
-
|
1902
|
-
|
1903
|
-
|
1904
|
-
|
1905
|
-
|
1906
|
-
|
1907
|
-
|
1908
|
-
|
1909
|
-
|
1910
|
-
|
1911
|
-
|
1912
|
-
|
1913
|
-
|
1914
|
-
|
1915
|
-
|
1916
|
-
|
2108
|
+
falseys, truthys = partition_flatten_types(rhs_type) do |type|
|
2109
|
+
type.is_a?(AST::Types::Nil) || (type.is_a?(AST::Types::Literal) && type.value == false)
|
2110
|
+
end
|
2111
|
+
|
2112
|
+
unwrap_rhs_type = AST::Types::Union.build(types: truthys)
|
2113
|
+
|
2114
|
+
case
|
2115
|
+
when unwrap_rhs_type.is_a?(AST::Types::Tuple) || (rhs.type == :array && rhs.children.none? {|n| n.type == :splat })
|
2116
|
+
tuple_types = if unwrap_rhs_type.is_a?(AST::Types::Tuple)
|
2117
|
+
unwrap_rhs_type.types.dup
|
2118
|
+
else
|
2119
|
+
rhs.children.map do |node|
|
2120
|
+
typing.type_of(node: node)
|
2121
|
+
end
|
2122
|
+
end
|
2123
|
+
|
2124
|
+
assignment_nodes = lhs.children.dup
|
2125
|
+
leading_assignments = []
|
2126
|
+
trailing_assignments = []
|
2127
|
+
|
2128
|
+
until assignment_nodes.empty?
|
2129
|
+
cursor = assignment_nodes.first
|
2130
|
+
|
2131
|
+
if cursor.type == :splat
|
2132
|
+
break
|
2133
|
+
else
|
2134
|
+
leading_assignments << assignment_nodes.shift
|
1917
2135
|
end
|
2136
|
+
end
|
1918
2137
|
|
1919
|
-
|
2138
|
+
until assignment_nodes.empty?
|
2139
|
+
cursor = assignment_nodes.last
|
1920
2140
|
|
1921
|
-
|
1922
|
-
|
2141
|
+
if cursor.type == :splat
|
2142
|
+
break
|
2143
|
+
else
|
2144
|
+
trailing_assignments.unshift assignment_nodes.pop
|
2145
|
+
end
|
2146
|
+
end
|
1923
2147
|
|
1924
|
-
|
1925
|
-
|
2148
|
+
leading_assignments.each do |asgn|
|
2149
|
+
type = tuple_types.first
|
1926
2150
|
|
1927
|
-
|
1928
|
-
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
Errors::IncompatibleAssignment.new(node: lhs,
|
1933
|
-
lhs_type: declared_type,
|
1934
|
-
rhs_type: type,
|
1935
|
-
result: result)
|
1936
|
-
)
|
1937
|
-
end
|
1938
|
-
add_typing(lhs,
|
1939
|
-
type: ty,
|
1940
|
-
constr: ctr.with_updated_context(lvar_env: env)).constr
|
1941
|
-
when :ivasgn
|
1942
|
-
ivar = lhs.children[0]
|
2151
|
+
if type
|
2152
|
+
tuple_types.shift
|
2153
|
+
else
|
2154
|
+
type = AST::Builtin.nil_type
|
2155
|
+
end
|
1943
2156
|
|
1944
|
-
|
1945
|
-
|
1946
|
-
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
result: error))
|
1952
|
-
when nil
|
1953
|
-
fallback_to_any node
|
1954
|
-
end
|
1955
|
-
end
|
2157
|
+
case asgn.type
|
2158
|
+
when :lvasgn
|
2159
|
+
_, constr = constr.lvasgn(asgn, type)
|
2160
|
+
when :ivasgn
|
2161
|
+
_, constr = constr.ivasgn(asgn, type)
|
2162
|
+
end
|
2163
|
+
end
|
1956
2164
|
|
1957
|
-
|
1958
|
-
|
2165
|
+
trailing_assignments.reverse_each do |asgn|
|
2166
|
+
type = tuple_types.last
|
2167
|
+
|
2168
|
+
if type
|
2169
|
+
tuple_types.pop
|
2170
|
+
else
|
2171
|
+
type = AST::Builtin.nil_type
|
1959
2172
|
end
|
1960
2173
|
|
1961
|
-
|
2174
|
+
case asgn.type
|
2175
|
+
when :lvasgn
|
2176
|
+
_, constr = constr.lvasgn(asgn, type)
|
2177
|
+
when :ivasgn
|
2178
|
+
_, constr = constr.ivasgn(asgn, type)
|
2179
|
+
end
|
2180
|
+
end
|
1962
2181
|
|
1963
|
-
|
1964
|
-
|
2182
|
+
element_type = if tuple_types.empty?
|
2183
|
+
AST::Builtin.nil_type
|
2184
|
+
else
|
2185
|
+
AST::Types::Union.build(types: tuple_types)
|
2186
|
+
end
|
2187
|
+
array_type = AST::Builtin::Array.instance_type(element_type)
|
1965
2188
|
|
1966
|
-
|
1967
|
-
|
2189
|
+
assignment_nodes.each do |asgn|
|
2190
|
+
case asgn.type
|
2191
|
+
when :splat
|
2192
|
+
case asgn.children[0].type
|
1968
2193
|
when :lvasgn
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
|
1973
|
-
|
1974
|
-
|
1975
|
-
|
1976
|
-
|
1977
|
-
|
2194
|
+
_, constr = constr.lvasgn(asgn.children[0], array_type)
|
2195
|
+
when :ivasgn
|
2196
|
+
_, constr = constr.ivasgn(asgn.children[0], array_type)
|
2197
|
+
end
|
2198
|
+
when :lvasgn
|
2199
|
+
_, constr = constr.lvasgn(asgn, element_type)
|
2200
|
+
when :ivasgn
|
2201
|
+
_,constr = constr.ivasgn(asgn, element_type)
|
2202
|
+
end
|
2203
|
+
end
|
2204
|
+
|
2205
|
+
unless falseys.empty?
|
2206
|
+
constr = constr.update_lvar_env {|lvar_env| self.context.lvar_env.join(lvar_env, self.context.lvar_env)}
|
2207
|
+
end
|
1978
2208
|
|
1979
|
-
|
1980
|
-
type: element_type,
|
1981
|
-
constr: ctr.with_updated_context(lvar_env: env)).constr
|
2209
|
+
add_typing(node, type: rhs_type, constr: constr)
|
1982
2210
|
|
1983
|
-
|
1984
|
-
|
2211
|
+
when flatten_union(unwrap_rhs_type).all? {|type| AST::Builtin::Array.instance_type?(type) }
|
2212
|
+
array_elements = flatten_union(unwrap_rhs_type).map {|type| type.args[0] }
|
2213
|
+
element_type = AST::Types::Union.build(types: array_elements + [AST::Builtin.nil_type])
|
1985
2214
|
|
1986
|
-
|
1987
|
-
|
1988
|
-
|
1989
|
-
|
1990
|
-
typing.add_error(Errors::IncompatibleAssignment.new(node: assignment,
|
1991
|
-
lhs_type: type,
|
1992
|
-
rhs_type: element_type,
|
1993
|
-
result: error))
|
1994
|
-
when nil
|
1995
|
-
fallback_to_any node
|
1996
|
-
end
|
1997
|
-
end
|
2215
|
+
constr = lhs.children.inject(constr) do |constr, assignment|
|
2216
|
+
case assignment.type
|
2217
|
+
when :lvasgn
|
2218
|
+
_, constr = constr.lvasgn(assignment, element_type)
|
1998
2219
|
|
1999
|
-
|
2220
|
+
when :ivasgn
|
2221
|
+
_, constr = constr.ivasgn(assignment, element_type)
|
2222
|
+
when :splat
|
2223
|
+
case assignment.children[0].type
|
2224
|
+
when :lvasgn
|
2225
|
+
_, constr = constr.lvasgn(assignment.children[0], unwrap_rhs_type)
|
2226
|
+
when :ivasgn
|
2227
|
+
_, constr = constr.ivasgn(assignment.children[0], unwrap_rhs_type)
|
2228
|
+
else
|
2229
|
+
raise
|
2000
2230
|
end
|
2001
2231
|
end
|
2002
2232
|
|
2003
|
-
|
2004
|
-
|
2005
|
-
when rhs_type.is_a?(AST::Types::Any)
|
2006
|
-
fallback_to_any(node)
|
2233
|
+
constr
|
2234
|
+
end
|
2007
2235
|
|
2008
|
-
|
2009
|
-
|
2010
|
-
fallback_to_any(node)
|
2236
|
+
unless falseys.empty?
|
2237
|
+
constr = constr.update_lvar_env {|lvar_env| self.context.lvar_env.join(lvar_env, self.context.lvar_env)}
|
2011
2238
|
end
|
2239
|
+
|
2240
|
+
add_typing(node, type: rhs_type, constr: constr)
|
2012
2241
|
else
|
2013
|
-
|
2014
|
-
|
2242
|
+
unless rhs_type.is_a?(AST::Types::Any)
|
2243
|
+
Steep.logger.error("Unsupported masgn rhs type: array or tuple is supported (#{rhs_type})")
|
2244
|
+
end
|
2245
|
+
_, constr = constr.fallback_to_any(lhs)
|
2246
|
+
add_typing(node, type: rhs_type, constr: constr)
|
2015
2247
|
end
|
2016
2248
|
end
|
2017
2249
|
|
@@ -2062,7 +2294,7 @@ module Steep
|
|
2062
2294
|
else
|
2063
2295
|
case expanded_receiver_type = expand_self(receiver_type)
|
2064
2296
|
when AST::Types::Self
|
2065
|
-
Steep.logger.
|
2297
|
+
Steep.logger.debug { "`self` type cannot be resolved to concrete type" }
|
2066
2298
|
fallback_to_any node do
|
2067
2299
|
Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2068
2300
|
end
|
@@ -2203,139 +2435,68 @@ module Steep
|
|
2203
2435
|
def type_method_call(node, method_name:, receiver_type:, method:, args:, block_params:, block_body:, topdown_hint:)
|
2204
2436
|
node_range = node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
|
2205
2437
|
|
2206
|
-
|
2207
|
-
|
2208
|
-
|
2209
|
-
|
2438
|
+
results = method.method_types.flat_map do |method_type|
|
2439
|
+
Steep.logger.tagged method_type.to_s do
|
2440
|
+
zips = args.zips(method_type.params, method_type.block&.type)
|
2441
|
+
|
2442
|
+
zips.map do |arg_pairs|
|
2210
2443
|
typing.new_child(node_range) do |child_typing|
|
2211
|
-
with_new_typing(child_typing).
|
2212
|
-
|
2213
|
-
|
2214
|
-
|
2215
|
-
|
2216
|
-
|
2217
|
-
|
2218
|
-
|
2219
|
-
|
2220
|
-
|
2444
|
+
ret = self.with_new_typing(child_typing).try_method_type(
|
2445
|
+
node,
|
2446
|
+
receiver_type: receiver_type,
|
2447
|
+
method_type: method_type,
|
2448
|
+
args: args,
|
2449
|
+
arg_pairs: arg_pairs,
|
2450
|
+
block_params: block_params,
|
2451
|
+
block_body: block_body,
|
2452
|
+
child_typing: child_typing,
|
2453
|
+
topdown_hint: topdown_hint
|
2454
|
+
)
|
2221
2455
|
|
2222
|
-
|
2223
|
-
constr.typing.save!
|
2224
|
-
[type,
|
2225
|
-
update_lvar_env { constr.context.lvar_env },
|
2226
|
-
error]
|
2227
|
-
else
|
2228
|
-
types = results.map(&:first)
|
2456
|
+
raise unless ret.is_a?(Array) && ret[1].is_a?(TypeConstruction)
|
2229
2457
|
|
2230
|
-
|
2231
|
-
constr.typing.save!
|
2458
|
+
result, constr = ret
|
2232
2459
|
|
2233
|
-
|
2234
|
-
|
2235
|
-
nil]
|
2460
|
+
[result, constr, method_type]
|
2461
|
+
end
|
2236
2462
|
end
|
2237
2463
|
end
|
2464
|
+
end
|
2238
2465
|
|
2239
|
-
|
2240
|
-
|
2241
|
-
|
2242
|
-
|
2243
|
-
|
2466
|
+
unless results.empty?
|
2467
|
+
result, constr, method_type = results.find {|result, _, _| !result.is_a?(Errors::Base) } || results.last
|
2468
|
+
else
|
2469
|
+
method_type = method.method_types.last
|
2470
|
+
constr = self.with_new_typing(typing.new_child(node_range))
|
2471
|
+
result = Errors::IncompatibleArguments.new(node: node, receiver_type: receiver_type, method_type: method_type)
|
2472
|
+
end
|
2473
|
+
constr.typing.save!
|
2474
|
+
|
2475
|
+
case result
|
2476
|
+
when Errors::Base
|
2477
|
+
if method.method_types.size == 1
|
2478
|
+
typing.add_error result
|
2479
|
+
type = case method_type.return_type
|
2480
|
+
when AST::Types::Var
|
2481
|
+
AST::Builtin.any_type
|
2482
|
+
else
|
2483
|
+
method_type.return_type
|
2484
|
+
end
|
2485
|
+
else
|
2486
|
+
typing.add_error Errors::UnresolvedOverloading.new(node: node,
|
2487
|
+
receiver_type: expand_self(receiver_type),
|
2244
2488
|
method_name: method_name,
|
2245
|
-
|
2246
|
-
|
2247
|
-
args: args,
|
2248
|
-
block_params: block_params,
|
2249
|
-
block_body: block_body,
|
2250
|
-
topdown_hint: false)
|
2251
|
-
end
|
2252
|
-
end
|
2253
|
-
|
2254
|
-
successes = results.reject {|_, _, error| error }
|
2255
|
-
unless successes.empty?
|
2256
|
-
types = successes.map(&:first)
|
2257
|
-
constr = successes[0][1]
|
2258
|
-
constr.typing.save!
|
2259
|
-
|
2260
|
-
[AST::Types::Intersection.build(types: types),
|
2261
|
-
update_lvar_env { constr.context.lvar_env },
|
2262
|
-
nil]
|
2263
|
-
else
|
2264
|
-
type, constr, error = results.first
|
2265
|
-
constr.typing.save!
|
2266
|
-
|
2267
|
-
[type,
|
2268
|
-
update_lvar_env { constr.context.lvar_env },
|
2269
|
-
error]
|
2270
|
-
end
|
2489
|
+
method_types: method.method_types)
|
2490
|
+
type = AST::Builtin.any_type
|
2271
2491
|
end
|
2272
2492
|
|
2273
|
-
|
2274
|
-
|
2275
|
-
|
2276
|
-
|
2277
|
-
|
2278
|
-
|
2279
|
-
|
2280
|
-
typing.new_child(node_range) do |child_typing|
|
2281
|
-
ret = self.with_new_typing(child_typing).try_method_type(
|
2282
|
-
node,
|
2283
|
-
receiver_type: receiver_type,
|
2284
|
-
method_type: method_type,
|
2285
|
-
args: args,
|
2286
|
-
arg_pairs: arg_pairs,
|
2287
|
-
block_params: block_params,
|
2288
|
-
block_body: block_body,
|
2289
|
-
child_typing: child_typing,
|
2290
|
-
topdown_hint: topdown_hint
|
2291
|
-
)
|
2292
|
-
|
2293
|
-
raise unless ret.is_a?(Array) && ret[1].is_a?(TypeConstruction)
|
2294
|
-
|
2295
|
-
result, constr = ret
|
2296
|
-
|
2297
|
-
[result, constr, method_type]
|
2298
|
-
end
|
2299
|
-
end
|
2300
|
-
end
|
2301
|
-
end
|
2302
|
-
|
2303
|
-
unless results.empty?
|
2304
|
-
result, constr, method_type = results.find {|result, _, _| !result.is_a?(Errors::Base) } || results.last
|
2305
|
-
else
|
2306
|
-
method_type = method.types.last
|
2307
|
-
constr = self.with_new_typing(typing.new_child(node_range))
|
2308
|
-
result = Errors::IncompatibleArguments.new(node: node, receiver_type: receiver_type, method_type: method_type)
|
2309
|
-
end
|
2310
|
-
constr.typing.save!
|
2311
|
-
|
2312
|
-
case result
|
2313
|
-
when Errors::Base
|
2314
|
-
if method.types.size == 1
|
2315
|
-
typing.add_error result
|
2316
|
-
type = case method_type.return_type
|
2317
|
-
when AST::Types::Var
|
2318
|
-
AST::Builtin.any_type
|
2319
|
-
else
|
2320
|
-
method_type.return_type
|
2321
|
-
end
|
2322
|
-
else
|
2323
|
-
typing.add_error Errors::UnresolvedOverloading.new(node: node,
|
2324
|
-
receiver_type: expand_self(receiver_type),
|
2325
|
-
method_name: method_name,
|
2326
|
-
method_types: method.types)
|
2327
|
-
type = AST::Builtin.any_type
|
2328
|
-
end
|
2329
|
-
|
2330
|
-
[type,
|
2331
|
-
update_lvar_env { constr.context.lvar_env },
|
2332
|
-
result]
|
2333
|
-
else # Type
|
2334
|
-
[result,
|
2335
|
-
update_lvar_env { constr.context.lvar_env },
|
2336
|
-
nil]
|
2337
|
-
end
|
2338
|
-
end
|
2493
|
+
[type,
|
2494
|
+
update_lvar_env { constr.context.lvar_env },
|
2495
|
+
result]
|
2496
|
+
else # Type
|
2497
|
+
[result,
|
2498
|
+
update_lvar_env { constr.context.lvar_env },
|
2499
|
+
nil]
|
2339
2500
|
end
|
2340
2501
|
end
|
2341
2502
|
|
@@ -2522,16 +2683,40 @@ module Steep
|
|
2522
2683
|
if block_params && method_type.block
|
2523
2684
|
block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
|
2524
2685
|
block_params_ = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
|
2525
|
-
block_param_hint = block_params_.params_type(
|
2526
|
-
hint: topdown_hint ? method_type.block.type.params : nil
|
2527
|
-
)
|
2528
2686
|
|
2529
|
-
|
2530
|
-
|
2531
|
-
|
2532
|
-
|
2533
|
-
|
2534
|
-
|
2687
|
+
unless block_params_
|
2688
|
+
return [
|
2689
|
+
Errors::UnsupportedSyntax.new(
|
2690
|
+
node: block_params,
|
2691
|
+
message: "Unsupported block params pattern, probably masgn?"
|
2692
|
+
),
|
2693
|
+
constr
|
2694
|
+
]
|
2695
|
+
end
|
2696
|
+
|
2697
|
+
pairs = block_params_.zip(method_type.block.type.params)
|
2698
|
+
|
2699
|
+
unless pairs
|
2700
|
+
return [
|
2701
|
+
Errors::IncompatibleBlockParameters.new(node: node, method_type: method_type),
|
2702
|
+
constr
|
2703
|
+
]
|
2704
|
+
end
|
2705
|
+
|
2706
|
+
pairs.each do |param, type|
|
2707
|
+
if param.type
|
2708
|
+
check_relation(sub_type: type, super_type: param.type, constraints: constraints).else do |result|
|
2709
|
+
return [
|
2710
|
+
Errors::IncompatibleAssignment.new(
|
2711
|
+
node: param.node,
|
2712
|
+
lhs_type: param.type,
|
2713
|
+
rhs_type: type,
|
2714
|
+
result: result
|
2715
|
+
),
|
2716
|
+
constr
|
2717
|
+
]
|
2718
|
+
end
|
2719
|
+
end
|
2535
2720
|
end
|
2536
2721
|
end
|
2537
2722
|
|
@@ -3005,7 +3190,12 @@ module Steep
|
|
3005
3190
|
|
3006
3191
|
ty = case type
|
3007
3192
|
when AST::Types::Name::Alias
|
3008
|
-
deep_expand_alias(expand_alias(type), recursive: recursive
|
3193
|
+
deep_expand_alias(expand_alias(type), recursive: recursive.union([type]))
|
3194
|
+
when AST::Types::Union
|
3195
|
+
AST::Types::Union.build(
|
3196
|
+
types: type.types.map {|ty| deep_expand_alias(ty, recursive: recursive, &block) },
|
3197
|
+
location: type.location
|
3198
|
+
)
|
3009
3199
|
else
|
3010
3200
|
type
|
3011
3201
|
end
|
@@ -3017,19 +3207,51 @@ module Steep
|
|
3017
3207
|
end
|
3018
3208
|
end
|
3019
3209
|
|
3210
|
+
def flatten_union(type, acc = [])
|
3211
|
+
case type
|
3212
|
+
when AST::Types::Union
|
3213
|
+
type.types.each {|ty| flatten_union(ty, acc) }
|
3214
|
+
else
|
3215
|
+
acc << type
|
3216
|
+
end
|
3217
|
+
|
3218
|
+
acc
|
3219
|
+
end
|
3220
|
+
|
3221
|
+
def select_flatten_types(type, &block)
|
3222
|
+
types = flatten_union(deep_expand_alias(type))
|
3223
|
+
types.select(&block)
|
3224
|
+
end
|
3225
|
+
|
3226
|
+
def partition_flatten_types(type, &block)
|
3227
|
+
types = flatten_union(deep_expand_alias(type))
|
3228
|
+
types.partition(&block)
|
3229
|
+
end
|
3230
|
+
|
3231
|
+
def flatten_array_elements(type)
|
3232
|
+
flatten_union(deep_expand_alias(type)).flat_map do |type|
|
3233
|
+
if AST::Builtin::Array.instance_type?(type)
|
3234
|
+
type.args
|
3235
|
+
else
|
3236
|
+
[type]
|
3237
|
+
end
|
3238
|
+
end
|
3239
|
+
end
|
3240
|
+
|
3020
3241
|
def expand_alias(type, &block)
|
3021
3242
|
checker.factory.expand_alias(type, &block)
|
3022
3243
|
end
|
3023
3244
|
|
3024
3245
|
def test_literal_type(literal, hint)
|
3025
|
-
|
3026
|
-
|
3027
|
-
|
3028
|
-
|
3029
|
-
|
3030
|
-
|
3031
|
-
|
3032
|
-
|
3246
|
+
if hint
|
3247
|
+
case hint
|
3248
|
+
when AST::Types::Any
|
3249
|
+
nil
|
3250
|
+
else
|
3251
|
+
literal_type = AST::Types::Literal.new(value: literal, location: nil)
|
3252
|
+
if check_relation(sub_type: literal_type, super_type: hint).success?
|
3253
|
+
hint
|
3254
|
+
end
|
3033
3255
|
end
|
3034
3256
|
end
|
3035
3257
|
end
|
@@ -3054,7 +3276,7 @@ module Steep
|
|
3054
3276
|
|
3055
3277
|
def to_instance_type(type, args: nil)
|
3056
3278
|
args = args || case type
|
3057
|
-
when AST::Types::Name::
|
3279
|
+
when AST::Types::Name::Singleton
|
3058
3280
|
checker.factory.env.class_decls[checker.factory.type_name_1(type.name)].type_params.each.map { AST::Builtin.any_type }
|
3059
3281
|
else
|
3060
3282
|
raise "unexpected type to to_instance_type: #{type}"
|
@@ -3063,6 +3285,47 @@ module Steep
|
|
3063
3285
|
AST::Types::Name::Instance.new(name: type.name, args: args)
|
3064
3286
|
end
|
3065
3287
|
|
3288
|
+
def try_tuple_type(node, hint)
|
3289
|
+
if node.children.size != hint.types.size
|
3290
|
+
return
|
3291
|
+
end
|
3292
|
+
|
3293
|
+
constr = self
|
3294
|
+
element_types = []
|
3295
|
+
|
3296
|
+
each_child_node(node).with_index do |child, index|
|
3297
|
+
type, constr = constr.synthesize(child, hint: hint.types[index])
|
3298
|
+
element_types << type
|
3299
|
+
end
|
3300
|
+
|
3301
|
+
constr.add_typing(node, type: AST::Types::Tuple.new(types: element_types))
|
3302
|
+
end
|
3303
|
+
|
3304
|
+
def try_array_type(node, hint)
|
3305
|
+
element_hint = hint ? hint.args[0] : nil
|
3306
|
+
|
3307
|
+
constr = self
|
3308
|
+
element_types = []
|
3309
|
+
|
3310
|
+
each_child_node(node) do |child|
|
3311
|
+
case child.type
|
3312
|
+
when :splat
|
3313
|
+
type, constr = constr.synthesize(child.children[0], hint: hint)
|
3314
|
+
if AST::Builtin::Array.instance_type?(type)
|
3315
|
+
element_types << type.args[0]
|
3316
|
+
else
|
3317
|
+
element_types.push(*flatten_array_elements(type))
|
3318
|
+
end
|
3319
|
+
else
|
3320
|
+
type, constr = constr.synthesize(child, hint: element_hint)
|
3321
|
+
element_types << type
|
3322
|
+
end
|
3323
|
+
end
|
3324
|
+
|
3325
|
+
element_type = AST::Types::Union.build(types: element_types)
|
3326
|
+
constr.add_typing(node, type: AST::Builtin::Array.instance_type(element_type))
|
3327
|
+
end
|
3328
|
+
|
3066
3329
|
def try_hash_type(node, hint)
|
3067
3330
|
case hint
|
3068
3331
|
when AST::Types::Record
|