steep 0.22.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/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
|