steep 0.33.0 → 0.34.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 +7 -0
- data/lib/steep.rb +3 -0
- data/lib/steep/annotation_parser.rb +1 -1
- data/lib/steep/ast/types/factory.rb +63 -57
- data/lib/steep/cli.rb +14 -1
- data/lib/steep/drivers/stats.rb +85 -0
- data/lib/steep/errors.rb +19 -15
- data/lib/steep/interface/method_type.rb +12 -23
- data/lib/steep/method_name.rb +28 -0
- data/lib/steep/project/completion_provider.rb +24 -15
- data/lib/steep/project/source_file.rb +2 -1
- data/lib/steep/server/interaction_worker.rb +1 -1
- data/lib/steep/subtyping/variable_occurrence.rb +2 -0
- data/lib/steep/type_construction.rb +577 -415
- data/lib/steep/type_inference/context.rb +7 -3
- data/lib/steep/type_inference/local_variable_type_env.rb +10 -1
- data/lib/steep/type_inference/method_call.rb +116 -0
- data/lib/steep/typing.rb +38 -8
- data/lib/steep/version.rb +1 -1
- data/smoke/regression/range.rb +5 -0
- data/steep.gemspec +1 -1
- metadata +8 -4
@@ -774,16 +774,14 @@ module Steep
|
|
774
774
|
attr_reader :params
|
775
775
|
attr_reader :block
|
776
776
|
attr_reader :return_type
|
777
|
-
attr_reader :
|
778
|
-
attr_reader :method_def
|
777
|
+
attr_reader :method_decls
|
779
778
|
|
780
|
-
def initialize(type_params:, params:, block:, return_type:,
|
779
|
+
def initialize(type_params:, params:, block:, return_type:, method_decls:)
|
781
780
|
@type_params = type_params
|
782
781
|
@params = params
|
783
782
|
@block = block
|
784
783
|
@return_type = return_type
|
785
|
-
@
|
786
|
-
@method_def = method_def
|
784
|
+
@method_decls = method_decls
|
787
785
|
end
|
788
786
|
|
789
787
|
def ==(other)
|
@@ -791,9 +789,7 @@ module Steep
|
|
791
789
|
other.type_params == type_params &&
|
792
790
|
other.params == params &&
|
793
791
|
other.block == block &&
|
794
|
-
other.return_type == return_type
|
795
|
-
(!other.method_def || !method_def || other.method_def == method_def) &&
|
796
|
-
(!other.location || !location || other.location == location)
|
792
|
+
other.return_type == return_type
|
797
793
|
end
|
798
794
|
|
799
795
|
alias eql? ==
|
@@ -824,8 +820,7 @@ module Steep
|
|
824
820
|
params: params.subst(s_),
|
825
821
|
block: block&.subst(s_),
|
826
822
|
return_type: return_type.subst(s_),
|
827
|
-
|
828
|
-
location: location
|
823
|
+
method_decls: method_decls
|
829
824
|
)
|
830
825
|
end
|
831
826
|
|
@@ -847,17 +842,15 @@ module Steep
|
|
847
842
|
params: params.subst(s),
|
848
843
|
block: block&.subst(s),
|
849
844
|
return_type: return_type.subst(s),
|
850
|
-
|
851
|
-
method_def: method_def)
|
845
|
+
method_decls: method_decls)
|
852
846
|
end
|
853
847
|
|
854
|
-
def with(type_params: self.type_params, params: self.params, block: self.block, return_type: self.return_type,
|
848
|
+
def with(type_params: self.type_params, params: self.params, block: self.block, return_type: self.return_type, method_decls: self.method_decls)
|
855
849
|
self.class.new(type_params: type_params,
|
856
850
|
params: params,
|
857
851
|
block: block,
|
858
852
|
return_type: return_type,
|
859
|
-
|
860
|
-
location: location)
|
853
|
+
method_decls: method_decls)
|
861
854
|
end
|
862
855
|
|
863
856
|
def to_s
|
@@ -873,8 +866,7 @@ module Steep
|
|
873
866
|
params: params.map_type(&block),
|
874
867
|
block: self.block&.yield_self {|blk| blk.map_type(&block) },
|
875
868
|
return_type: yield(return_type),
|
876
|
-
|
877
|
-
method_def: method_def)
|
869
|
+
method_decls: method_decls)
|
878
870
|
end
|
879
871
|
|
880
872
|
# Returns a new method type which can be used for the method implementation type of both `self` and `other`.
|
@@ -902,8 +894,7 @@ module Steep
|
|
902
894
|
return_type: AST::Types::Union.build(
|
903
895
|
types: [return_type.subst(s1),other.return_type.subst(s2)]
|
904
896
|
),
|
905
|
-
|
906
|
-
location: nil
|
897
|
+
method_decls: method_decls + other.method_decls
|
907
898
|
)
|
908
899
|
end
|
909
900
|
|
@@ -958,8 +949,7 @@ module Steep
|
|
958
949
|
block: block,
|
959
950
|
return_type: return_type,
|
960
951
|
type_params: type_params,
|
961
|
-
|
962
|
-
location: nil
|
952
|
+
method_decls: method_decls + other.method_decls
|
963
953
|
)
|
964
954
|
end
|
965
955
|
|
@@ -1006,8 +996,7 @@ module Steep
|
|
1006
996
|
block: block,
|
1007
997
|
return_type: return_type,
|
1008
998
|
type_params: type_params,
|
1009
|
-
|
1010
|
-
location: nil
|
999
|
+
method_decls: method_decls + other.method_decls
|
1011
1000
|
)
|
1012
1001
|
end
|
1013
1002
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Steep
|
2
|
+
InstanceMethodName = Struct.new(:type_name, :method_name, keyword_init: true) do
|
3
|
+
def to_s
|
4
|
+
"#{type_name}##{method_name}"
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
SingletonMethodName = Struct.new(:type_name, :method_name, keyword_init: true) do
|
9
|
+
def to_s
|
10
|
+
"#{type_name}.#{method_name}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module ::Kernel
|
15
|
+
def MethodName(string)
|
16
|
+
case string
|
17
|
+
when /#/
|
18
|
+
type_name, method_name = string.split(/#/, 2)
|
19
|
+
InstanceMethodName.new(type_name: TypeName(type_name), method_name: method_name.to_sym)
|
20
|
+
when /\./
|
21
|
+
type_name, method_name = string.split(/\./, 2)
|
22
|
+
SingletonMethodName.new(type_name: TypeName(type_name), method_name: method_name.to_sym)
|
23
|
+
else
|
24
|
+
raise "Unexpected method name: #{string}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -10,9 +10,27 @@ module Steep
|
|
10
10
|
|
11
11
|
InstanceVariableItem = Struct.new(:identifier, :range, :type, keyword_init: true)
|
12
12
|
LocalVariableItem = Struct.new(:identifier, :range, :type, keyword_init: true)
|
13
|
-
MethodNameItem = Struct.new(:identifier, :range, :
|
13
|
+
MethodNameItem = Struct.new(:identifier, :range, :receiver_type, :method_type, :method_decls, keyword_init: true) do
|
14
14
|
def comment
|
15
|
-
|
15
|
+
case method_decls.size
|
16
|
+
when 0
|
17
|
+
nil
|
18
|
+
when 1
|
19
|
+
method_decls.to_a.first.method_def&.comment
|
20
|
+
else
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def inherited?
|
26
|
+
case receiver_type
|
27
|
+
when AST::Types::Name::Instance, AST::Types::Name::Singleton, AST::Types::Name::Interface
|
28
|
+
method_decls.any? do |decl|
|
29
|
+
decl.method_name.type_name != receiver_type.name
|
30
|
+
end
|
31
|
+
else
|
32
|
+
false
|
33
|
+
end
|
16
34
|
end
|
17
35
|
end
|
18
36
|
|
@@ -245,15 +263,15 @@ module Steep
|
|
245
263
|
items << MethodNameItem.new(
|
246
264
|
identifier: name,
|
247
265
|
range: range,
|
248
|
-
|
249
|
-
method_type:
|
250
|
-
|
266
|
+
receiver_type: type,
|
267
|
+
method_type: subtyping.factory.method_type_1(method_type, self_type: type),
|
268
|
+
method_decls: method_type.method_decls
|
251
269
|
)
|
252
270
|
end
|
253
271
|
end
|
254
272
|
end
|
255
273
|
end
|
256
|
-
rescue
|
274
|
+
rescue RuntimeError => exn
|
257
275
|
# nop
|
258
276
|
end
|
259
277
|
|
@@ -298,15 +316,6 @@ module Steep
|
|
298
316
|
index
|
299
317
|
end
|
300
318
|
|
301
|
-
def inherited_method?(method_def, type)
|
302
|
-
case type
|
303
|
-
when AST::Types::Name::Instance, AST::Types::Name::Singleton, AST::Types::Name::Interface
|
304
|
-
method_def.implemented_in != type.name
|
305
|
-
else
|
306
|
-
false
|
307
|
-
end
|
308
|
-
end
|
309
|
-
|
310
319
|
def disallowed_method?(name)
|
311
320
|
# initialize isn't invoked by developers when creating
|
312
321
|
# instances of new classes, so don't show it as
|
@@ -66,7 +66,8 @@ module Steep
|
|
66
66
|
break_context: nil,
|
67
67
|
self_type: AST::Builtin::Object.instance_type,
|
68
68
|
type_env: type_env,
|
69
|
-
lvar_env: lvar_env
|
69
|
+
lvar_env: lvar_env,
|
70
|
+
call_context: TypeInference::MethodCall::TopLevelContext.new
|
70
71
|
)
|
71
72
|
|
72
73
|
typing = Typing.new(source: source, root_context: context)
|
@@ -196,7 +196,7 @@ HOVER
|
|
196
196
|
),
|
197
197
|
documentation: item.comment&.string,
|
198
198
|
insert_text_format: LanguageServer::Protocol::Constant::InsertTextFormat::SNIPPET,
|
199
|
-
sort_text: item.
|
199
|
+
sort_text: item.inherited? ? 'z' : 'a' # Ensure language server puts non-inherited methods before inherited methods
|
200
200
|
)
|
201
201
|
when Project::CompletionProvider::InstanceVariableItem
|
202
202
|
label = "#{item.identifier}: #{item.type}"
|
@@ -131,7 +131,7 @@ module Steep
|
|
131
131
|
definition_method_type = if definition
|
132
132
|
definition.methods[method_name]&.yield_self do |method|
|
133
133
|
method.method_types
|
134
|
-
.map {|method_type| checker.factory.method_type(method_type, self_type: self_type) }
|
134
|
+
.map {|method_type| checker.factory.method_type(method_type, self_type: self_type, method_decls: Set[]) }
|
135
135
|
.select {|method_type| method_type.is_a?(Interface::MethodType) }
|
136
136
|
.inject {|t1, t2| t1 + t2}
|
137
137
|
end
|
@@ -216,6 +216,21 @@ module Steep
|
|
216
216
|
|
217
217
|
lvar_env = lvar_env.annotate(annots)
|
218
218
|
|
219
|
+
call_context = case self_type
|
220
|
+
when nil
|
221
|
+
TypeInference::MethodCall::UnknownContext.new()
|
222
|
+
when AST::Types::Name::Singleton
|
223
|
+
TypeInference::MethodCall::MethodContext.new(
|
224
|
+
method_name: SingletonMethodName.new(type_name: module_context.class_name, method_name: method_name)
|
225
|
+
)
|
226
|
+
when AST::Types::Name::Instance, AST::Types::Intersection
|
227
|
+
TypeInference::MethodCall::MethodContext.new(
|
228
|
+
method_name: InstanceMethodName.new(type_name: module_context.class_name, method_name: method_name)
|
229
|
+
)
|
230
|
+
else
|
231
|
+
raise "Unexpected self_type: #{self_type}"
|
232
|
+
end
|
233
|
+
|
219
234
|
self.class.new(
|
220
235
|
checker: checker,
|
221
236
|
source: source,
|
@@ -227,7 +242,8 @@ module Steep
|
|
227
242
|
break_context: nil,
|
228
243
|
self_type: annots.self_type || self_type,
|
229
244
|
type_env: type_env,
|
230
|
-
lvar_env: lvar_env
|
245
|
+
lvar_env: lvar_env,
|
246
|
+
call_context: call_context
|
231
247
|
),
|
232
248
|
typing: typing,
|
233
249
|
)
|
@@ -355,7 +371,8 @@ module Steep
|
|
355
371
|
module_context: module_context_,
|
356
372
|
self_type: module_context_.module_type,
|
357
373
|
type_env: module_type_env,
|
358
|
-
lvar_env: lvar_env
|
374
|
+
lvar_env: lvar_env,
|
375
|
+
call_context: TypeInference::MethodCall::ModuleContext.new(type_name: module_context_.class_name)
|
359
376
|
)
|
360
377
|
)
|
361
378
|
end
|
@@ -424,7 +441,8 @@ module Steep
|
|
424
441
|
break_context: nil,
|
425
442
|
self_type: module_context.module_type,
|
426
443
|
type_env: class_type_env,
|
427
|
-
lvar_env: lvar_env
|
444
|
+
lvar_env: lvar_env,
|
445
|
+
call_context: TypeInference::MethodCall::ModuleContext.new(type_name: module_context.class_name)
|
428
446
|
)
|
429
447
|
|
430
448
|
self.class.new(
|
@@ -509,7 +527,8 @@ module Steep
|
|
509
527
|
break_context: nil,
|
510
528
|
self_type: module_context.module_type,
|
511
529
|
type_env: type_env,
|
512
|
-
lvar_env: lvar_env
|
530
|
+
lvar_env: lvar_env,
|
531
|
+
call_context: TypeInference::MethodCall::ModuleContext.new(type_name: module_context.class_name)
|
513
532
|
)
|
514
533
|
|
515
534
|
self.class.new(
|
@@ -608,6 +627,22 @@ module Steep
|
|
608
627
|
Pair.new(type: type, constr: constr)
|
609
628
|
end
|
610
629
|
|
630
|
+
def add_call(call)
|
631
|
+
case call
|
632
|
+
when TypeInference::MethodCall::NoMethodError
|
633
|
+
typing.add_error(call.error)
|
634
|
+
when TypeInference::MethodCall::Error
|
635
|
+
call.errors.each do |error|
|
636
|
+
typing.add_error(error)
|
637
|
+
end
|
638
|
+
end
|
639
|
+
|
640
|
+
typing.add_typing(call.node, call.return_type, nil)
|
641
|
+
typing.add_call(call.node, call)
|
642
|
+
|
643
|
+
Pair.new(type: call.return_type, constr: self)
|
644
|
+
end
|
645
|
+
|
611
646
|
def synthesize(node, hint: nil)
|
612
647
|
Steep.logger.tagged "synthesize:(#{node.location.expression.to_s.split(/:/, 2).last})" do
|
613
648
|
Steep.logger.debug node.type
|
@@ -786,28 +821,33 @@ module Steep
|
|
786
821
|
when :super
|
787
822
|
yield_self do
|
788
823
|
if self_type && method_context&.method
|
789
|
-
if method_context.super_method
|
824
|
+
if super_def = method_context.super_method
|
790
825
|
each_child_node(node) do |child|
|
791
826
|
synthesize(child)
|
792
827
|
end
|
793
828
|
|
794
829
|
super_method = Interface::Interface::Entry.new(
|
795
830
|
method_types: method_context.super_method.method_types.map {|method_type|
|
796
|
-
|
831
|
+
decl = TypeInference::MethodCall::MethodDecl.new(
|
832
|
+
method_name: InstanceMethodName.new(type_name: super_def.implemented_in || super_def.defined_in,
|
833
|
+
method_name: method_context.name),
|
834
|
+
method_def: super_def
|
835
|
+
)
|
836
|
+
checker.factory.method_type(method_type, self_type: self_type, method_decls: Set[decl])
|
797
837
|
}
|
798
838
|
)
|
799
839
|
args = TypeInference::SendArgs.from_nodes(node.children.dup)
|
800
840
|
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
841
|
+
call, constr = type_method_call(node,
|
842
|
+
receiver_type: self_type,
|
843
|
+
method_name: method_context.name,
|
844
|
+
method: super_method,
|
845
|
+
args: args,
|
846
|
+
block_params: nil,
|
847
|
+
block_body: nil,
|
848
|
+
topdown_hint: true)
|
809
849
|
|
810
|
-
|
850
|
+
constr.add_call(call)
|
811
851
|
else
|
812
852
|
fallback_to_any node do
|
813
853
|
Errors::UnexpectedSuper.new(node: node, method: method_context.name)
|
@@ -1208,7 +1248,13 @@ module Steep
|
|
1208
1248
|
|
1209
1249
|
when :class
|
1210
1250
|
yield_self do
|
1211
|
-
|
1251
|
+
constr = self
|
1252
|
+
|
1253
|
+
name, sup, _ = node.children
|
1254
|
+
_, constr = constr.synthesize(name)
|
1255
|
+
_, constr = constr.synthesize(sup) if sup
|
1256
|
+
|
1257
|
+
constr.for_class(node).tap do |constructor|
|
1212
1258
|
constructor.typing.add_context_for_node(node, context: constructor.context)
|
1213
1259
|
constructor.typing.add_context_for_body(node, context: constructor.context)
|
1214
1260
|
|
@@ -1224,6 +1270,11 @@ module Steep
|
|
1224
1270
|
|
1225
1271
|
when :module
|
1226
1272
|
yield_self do
|
1273
|
+
constr = self
|
1274
|
+
|
1275
|
+
name, _ = node.children
|
1276
|
+
_, constr = constr.synthesize(name)
|
1277
|
+
|
1227
1278
|
for_module(node).yield_self do |constructor|
|
1228
1279
|
constructor.typing.add_context_for_node(node, context: constructor.context)
|
1229
1280
|
constructor.typing.add_context_for_body(node, context: constructor.context)
|
@@ -1271,24 +1322,39 @@ module Steep
|
|
1271
1322
|
when :self
|
1272
1323
|
add_typing node, type: AST::Types::Self.new
|
1273
1324
|
|
1325
|
+
when :cbase
|
1326
|
+
add_typing node, type: AST::Types::Void.new
|
1327
|
+
|
1274
1328
|
when :const
|
1275
|
-
|
1329
|
+
parent = node.children[0]
|
1330
|
+
if parent
|
1331
|
+
_, constr = synthesize(parent)
|
1332
|
+
else
|
1333
|
+
constr = self
|
1334
|
+
end
|
1335
|
+
|
1336
|
+
const_name = constr.module_name_from_node(node)
|
1276
1337
|
|
1277
1338
|
if const_name
|
1278
1339
|
type = type_env.get(const: const_name) do
|
1279
|
-
fallback_to_any
|
1340
|
+
constr.fallback_to_any(node)
|
1280
1341
|
end
|
1281
|
-
add_typing
|
1342
|
+
constr.add_typing(node, type: type)
|
1282
1343
|
else
|
1283
|
-
fallback_to_any
|
1344
|
+
constr.fallback_to_any(node)
|
1284
1345
|
end
|
1285
1346
|
|
1286
1347
|
when :casgn
|
1287
1348
|
yield_self do
|
1288
|
-
|
1349
|
+
constr = self
|
1350
|
+
|
1351
|
+
parent = node.children[0]
|
1352
|
+
_, constr = constr.synthesize(parent) if parent
|
1353
|
+
const_name = constr.module_name_from_node(node)
|
1354
|
+
|
1289
1355
|
if const_name
|
1290
1356
|
const_type = type_env.get(const: const_name) {}
|
1291
|
-
value_type = synthesize(node.children.last, hint: const_type)
|
1357
|
+
value_type, constr = constr.synthesize(node.children.last, hint: const_type)
|
1292
1358
|
type = type_env.assign(const: const_name, type: value_type, self_type: self_type) do |error|
|
1293
1359
|
case error
|
1294
1360
|
when Subtyping::Result::Failure
|
@@ -1302,10 +1368,10 @@ module Steep
|
|
1302
1368
|
end
|
1303
1369
|
end
|
1304
1370
|
|
1305
|
-
add_typing(node, type: type)
|
1371
|
+
constr.add_typing(node, type: type)
|
1306
1372
|
else
|
1307
|
-
synthesize(node.children.last)
|
1308
|
-
fallback_to_any(node)
|
1373
|
+
_, constr = constr.synthesize(node.children.last)
|
1374
|
+
constr.fallback_to_any(node)
|
1309
1375
|
end
|
1310
1376
|
end
|
1311
1377
|
|
@@ -1338,7 +1404,7 @@ module Steep
|
|
1338
1404
|
if method_context&.method
|
1339
1405
|
if method_context.super_method
|
1340
1406
|
types = method_context.super_method.method_types.map {|method_type|
|
1341
|
-
checker.factory.method_type(method_type, self_type: self_type).return_type
|
1407
|
+
checker.factory.method_type(method_type, self_type: self_type, method_decls: Set[]).return_type
|
1342
1408
|
}
|
1343
1409
|
add_typing(node, type: union_type(*types))
|
1344
1410
|
else
|
@@ -2029,7 +2095,7 @@ module Steep
|
|
2029
2095
|
unless pair.is_a?(Pair) && !pair.type.is_a?(Pair)
|
2030
2096
|
# Steep.logger.error { "result = #{pair.inspect}" }
|
2031
2097
|
# Steep.logger.error { "node = #{node.type}" }
|
2032
|
-
raise "#synthesize should return an instance of Pair: #{pair.class}"
|
2098
|
+
raise "#synthesize should return an instance of Pair: #{pair.class}, node=#{node.inspect}"
|
2033
2099
|
end
|
2034
2100
|
end
|
2035
2101
|
end
|
@@ -2273,177 +2339,222 @@ module Steep
|
|
2273
2339
|
return_hint = type_hint.return_type
|
2274
2340
|
end
|
2275
2341
|
|
2276
|
-
|
2277
|
-
|
2278
|
-
|
2279
|
-
|
2280
|
-
|
2281
|
-
|
2282
|
-
block_annotations: block_annotations,
|
2283
|
-
topdown_hint: true)
|
2342
|
+
block_constr = for_block(
|
2343
|
+
block_params: params,
|
2344
|
+
block_param_hint: params_hint,
|
2345
|
+
block_annotations: block_annotations,
|
2346
|
+
node_type_hint: nil
|
2347
|
+
)
|
2284
2348
|
|
2285
|
-
|
2286
|
-
end
|
2349
|
+
block_constr.typing.add_context_for_body(node, context: block_constr.context)
|
2287
2350
|
|
2288
|
-
|
2289
|
-
|
2290
|
-
|
2351
|
+
params.params.each do |param|
|
2352
|
+
_, block_constr = block_constr.synthesize(param.node, hint: param.type)
|
2353
|
+
end
|
2291
2354
|
|
2292
|
-
if
|
2293
|
-
|
2355
|
+
if block_body
|
2356
|
+
return_type = block_constr.synthesize_block(
|
2357
|
+
node: node,
|
2358
|
+
block_body: block_body,
|
2359
|
+
topdown_hint: true,
|
2360
|
+
block_type_hint: return_hint
|
2361
|
+
) do |error|
|
2362
|
+
typing.add_error(error)
|
2363
|
+
end
|
2364
|
+
else
|
2365
|
+
return_type = AST::Builtin.any_type
|
2294
2366
|
end
|
2295
2367
|
|
2296
|
-
|
2368
|
+
block_type = AST::Types::Proc.new(
|
2369
|
+
params: params_hint || params.params_type,
|
2370
|
+
return_type: return_type
|
2371
|
+
)
|
2297
2372
|
|
2298
|
-
|
2299
|
-
|
2300
|
-
each_child_node(send_node) do |child|
|
2301
|
-
unless child.equal?(receiver)
|
2302
|
-
_, constr = constr.synthesize(child)
|
2303
|
-
end
|
2304
|
-
end
|
2373
|
+
add_typing node, type: block_type
|
2374
|
+
end
|
2305
2375
|
|
2306
|
-
|
2376
|
+
def synthesize_children(node, skips: [])
|
2377
|
+
skips = Set.new.compare_by_identity.merge(skips)
|
2307
2378
|
|
2308
|
-
|
2309
|
-
fallback_to_any node
|
2379
|
+
constr = self
|
2310
2380
|
|
2311
|
-
|
2312
|
-
|
2313
|
-
|
2314
|
-
|
2381
|
+
each_child_node(node) do |child|
|
2382
|
+
unless skips.include?(child)
|
2383
|
+
_, constr = constr.synthesize(child)
|
2384
|
+
end
|
2385
|
+
end
|
2315
2386
|
|
2316
|
-
|
2317
|
-
|
2318
|
-
when AST::Types::Self
|
2319
|
-
Steep.logger.debug { "`self` type cannot be resolved to concrete type" }
|
2320
|
-
fallback_to_any node do
|
2321
|
-
Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2322
|
-
end
|
2323
|
-
else
|
2324
|
-
begin
|
2325
|
-
interface = checker.factory.interface(receiver_type,
|
2326
|
-
private: !receiver,
|
2327
|
-
self_type: expanded_receiver_type)
|
2328
|
-
|
2329
|
-
method = interface.methods[method_name]
|
2330
|
-
|
2331
|
-
if method
|
2332
|
-
args = TypeInference::SendArgs.from_nodes(arguments)
|
2333
|
-
return_type, constr, _ = constr.type_method_call(node,
|
2334
|
-
method: method,
|
2335
|
-
method_name: method_name,
|
2336
|
-
args: args,
|
2337
|
-
block_params: block_params,
|
2338
|
-
block_body: block_body,
|
2339
|
-
receiver_type: receiver_type,
|
2340
|
-
topdown_hint: true)
|
2341
|
-
|
2342
|
-
add_typing node, type: return_type, constr: constr
|
2343
|
-
else
|
2344
|
-
fallback_to_any node do
|
2345
|
-
Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
|
2346
|
-
end
|
2347
|
-
end
|
2348
|
-
rescue => exn
|
2349
|
-
case exn
|
2350
|
-
when RBS::NoTypeFoundError, RBS::NoMixinFoundError, RBS::NoSuperclassFoundError, RBS::InvalidTypeApplicationError
|
2351
|
-
# ignore known RBS errors.
|
2352
|
-
else
|
2353
|
-
Steep.log_error(exn, message: "Unexpected error in #type_send: #{exn.message} (#{exn.class})")
|
2354
|
-
end
|
2387
|
+
constr
|
2388
|
+
end
|
2355
2389
|
|
2356
|
-
|
2357
|
-
|
2358
|
-
end
|
2359
|
-
end
|
2360
|
-
end
|
2361
|
-
end
|
2390
|
+
def type_send_interface(node, interface:, receiver:, receiver_type:, method_name:, arguments:, block_params:, block_body:)
|
2391
|
+
method = interface.methods[method_name]
|
2362
2392
|
|
2363
|
-
|
2364
|
-
|
2365
|
-
|
2366
|
-
|
2367
|
-
|
2368
|
-
|
2369
|
-
|
2370
|
-
|
2371
|
-
|
2393
|
+
if method
|
2394
|
+
args = TypeInference::SendArgs.from_nodes(arguments)
|
2395
|
+
call, constr = type_method_call(node,
|
2396
|
+
method: method,
|
2397
|
+
method_name: method_name,
|
2398
|
+
args: args,
|
2399
|
+
block_params: block_params,
|
2400
|
+
block_body: block_body,
|
2401
|
+
receiver_type: receiver_type,
|
2402
|
+
topdown_hint: true)
|
2403
|
+
|
2404
|
+
if call && constr
|
2405
|
+
case method_name.to_s
|
2406
|
+
when "[]=", /\w=\Z/
|
2407
|
+
if typing.has_type?(arguments.last)
|
2408
|
+
call = call.with_return_type(typing.type_of(node: arguments.last))
|
2372
2409
|
end
|
2373
2410
|
end
|
2374
|
-
|
2375
|
-
|
2376
|
-
|
2377
|
-
|
2378
|
-
|
2379
|
-
|
2380
|
-
|
2381
|
-
|
2382
|
-
|
2383
|
-
|
2384
|
-
|
2385
|
-
|
2411
|
+
else
|
2412
|
+
error = Errors::UnresolvedOverloading.new(
|
2413
|
+
node: node,
|
2414
|
+
receiver_type: receiver_type,
|
2415
|
+
method_name: method_name,
|
2416
|
+
method_types: method.method_types
|
2417
|
+
)
|
2418
|
+
call = TypeInference::MethodCall::Error.new(
|
2419
|
+
node: node,
|
2420
|
+
context: context.method_context,
|
2421
|
+
method_name: method_name,
|
2422
|
+
receiver_type: receiver_type,
|
2423
|
+
errors: [error]
|
2424
|
+
)
|
2386
2425
|
|
2387
|
-
|
2426
|
+
constr = synthesize_children(node, skips: [receiver])
|
2427
|
+
if block_params
|
2428
|
+
block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
|
2388
2429
|
|
2389
|
-
|
2430
|
+
constr.type_block_without_hint(
|
2431
|
+
node: node,
|
2432
|
+
block_params: TypeInference::BlockParams.from_node(block_params, annotations: block_annotations),
|
2433
|
+
block_annotations: block_annotations,
|
2434
|
+
block_body: block_body
|
2435
|
+
) do |error|
|
2436
|
+
errors << error
|
2437
|
+
end
|
2390
2438
|
end
|
2391
2439
|
end
|
2440
|
+
|
2441
|
+
constr.add_call(call)
|
2392
2442
|
else
|
2393
|
-
|
2443
|
+
add_call(
|
2444
|
+
TypeInference::MethodCall::NoMethodError.new(
|
2445
|
+
node: node,
|
2446
|
+
context: context.method_context,
|
2447
|
+
method_name: method_name,
|
2448
|
+
receiver_type: receiver_type,
|
2449
|
+
error: Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2450
|
+
)
|
2451
|
+
)
|
2394
2452
|
end
|
2395
2453
|
end
|
2396
2454
|
|
2397
|
-
def
|
2398
|
-
|
2399
|
-
|
2400
|
-
if param.type
|
2401
|
-
env.set(lvar: param.var.name, type: param.type)
|
2402
|
-
else
|
2403
|
-
env.set(lvar: param.var.name, type: type)
|
2404
|
-
end
|
2405
|
-
end
|
2455
|
+
def type_send(node, send_node:, block_params:, block_body:, unwrap: false)
|
2456
|
+
receiver, method_name, *arguments = send_node.children
|
2457
|
+
recv_type, constr = receiver ? synthesize(receiver) : [AST::Types::Self.new, self]
|
2406
2458
|
|
2407
|
-
|
2408
|
-
|
2409
|
-
ivar_types: block_annotations.ivar_types,
|
2410
|
-
const_types: block_annotations.const_types,
|
2411
|
-
)
|
2459
|
+
if unwrap
|
2460
|
+
recv_type = unwrap(recv_type)
|
2412
2461
|
end
|
2413
2462
|
|
2414
|
-
|
2463
|
+
receiver_type = checker.factory.deep_expand_alias(recv_type)
|
2415
2464
|
|
2416
|
-
|
2417
|
-
|
2418
|
-
|
2419
|
-
method_return_type
|
2420
|
-
end
|
2421
|
-
Steep.logger.debug("return_type = #{return_type}")
|
2465
|
+
type, constr = case receiver_type
|
2466
|
+
when nil
|
2467
|
+
raise
|
2422
2468
|
|
2423
|
-
|
2424
|
-
|
2469
|
+
when AST::Types::Any
|
2470
|
+
constr = constr.synthesize_children(node, skips: [receiver])
|
2471
|
+
constr.add_call(
|
2472
|
+
TypeInference::MethodCall::Untyped.new(
|
2473
|
+
node: node,
|
2474
|
+
context: context.method_context,
|
2475
|
+
method_name: method_name
|
2476
|
+
)
|
2477
|
+
)
|
2425
2478
|
|
2426
|
-
|
2427
|
-
|
2428
|
-
|
2429
|
-
|
2430
|
-
|
2479
|
+
when AST::Types::Void, AST::Types::Bot, AST::Types::Top, AST::Types::Var
|
2480
|
+
constr = constr.synthesize_children(node, skips: [receiver])
|
2481
|
+
constr.add_call(
|
2482
|
+
TypeInference::MethodCall::NoMethodError.new(
|
2483
|
+
node: node,
|
2484
|
+
context: context.method_context,
|
2485
|
+
method_name: method_name,
|
2486
|
+
receiver_type: receiver_type,
|
2487
|
+
error: Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2488
|
+
)
|
2489
|
+
)
|
2431
2490
|
|
2432
|
-
|
2433
|
-
|
2434
|
-
|
2435
|
-
|
2436
|
-
|
2437
|
-
|
2438
|
-
|
2439
|
-
|
2440
|
-
|
2441
|
-
|
2442
|
-
|
2443
|
-
|
2444
|
-
|
2491
|
+
when AST::Types::Self
|
2492
|
+
expanded_self = expand_self(receiver_type)
|
2493
|
+
|
2494
|
+
if expanded_self.is_a?(AST::Types::Self)
|
2495
|
+
Steep.logger.debug { "`self` type cannot be resolved to concrete type" }
|
2496
|
+
|
2497
|
+
constr = constr.synthesize_children(node, skips: [receiver])
|
2498
|
+
constr.add_call(
|
2499
|
+
TypeInference::MethodCall::NoMethodError.new(
|
2500
|
+
node: node,
|
2501
|
+
context: context.method_context,
|
2502
|
+
method_name: method_name,
|
2503
|
+
receiver_type: receiver_type,
|
2504
|
+
error: Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2505
|
+
)
|
2506
|
+
)
|
2507
|
+
else
|
2508
|
+
interface = checker.factory.interface(expanded_self,
|
2509
|
+
private: !receiver,
|
2510
|
+
self_type: AST::Types::Self.new)
|
2511
|
+
|
2512
|
+
constr.type_send_interface(node,
|
2513
|
+
interface: interface,
|
2514
|
+
receiver: receiver,
|
2515
|
+
receiver_type: expanded_self,
|
2516
|
+
method_name: method_name,
|
2517
|
+
arguments: arguments,
|
2518
|
+
block_params: block_params,
|
2519
|
+
block_body: block_body)
|
2520
|
+
end
|
2521
|
+
else
|
2522
|
+
interface = checker.factory.interface(receiver_type,
|
2523
|
+
private: !receiver,
|
2524
|
+
self_type: receiver_type)
|
2525
|
+
|
2526
|
+
constr.type_send_interface(node,
|
2527
|
+
interface: interface,
|
2528
|
+
receiver: receiver,
|
2529
|
+
receiver_type: receiver_type,
|
2530
|
+
method_name: method_name,
|
2531
|
+
arguments: arguments,
|
2532
|
+
block_params: block_params,
|
2533
|
+
block_body: block_body)
|
2534
|
+
end
|
2535
|
+
|
2536
|
+
Pair.new(type: type, constr: constr)
|
2537
|
+
rescue => exn
|
2538
|
+
case exn
|
2539
|
+
when RBS::NoTypeFoundError, RBS::NoMixinFoundError, RBS::NoSuperclassFoundError, RBS::InvalidTypeApplicationError
|
2540
|
+
# ignore known RBS errors.
|
2541
|
+
else
|
2542
|
+
Steep.log_error(exn, message: "Unexpected error in #type_send: #{exn.message} (#{exn.class})")
|
2543
|
+
end
|
2544
|
+
|
2545
|
+
error = Errors::UnexpectedError.new(node: node, error: exn)
|
2546
|
+
|
2547
|
+
type_any_rec(node)
|
2548
|
+
|
2549
|
+
add_call(
|
2550
|
+
TypeInference::MethodCall::Error.new(
|
2551
|
+
node: node,
|
2552
|
+
context: context.method_context,
|
2553
|
+
method_name: method_name,
|
2554
|
+
receiver_type: receiver_type,
|
2555
|
+
errors: [error]
|
2445
2556
|
)
|
2446
|
-
)
|
2557
|
+
)
|
2447
2558
|
end
|
2448
2559
|
|
2449
2560
|
def expand_self(type)
|
@@ -2463,63 +2574,54 @@ module Steep
|
|
2463
2574
|
|
2464
2575
|
zips.map do |arg_pairs|
|
2465
2576
|
typing.new_child(node_range) do |child_typing|
|
2466
|
-
|
2577
|
+
self.with_new_typing(child_typing).try_method_type(
|
2467
2578
|
node,
|
2468
2579
|
receiver_type: receiver_type,
|
2580
|
+
method_name: method_name,
|
2469
2581
|
method_type: method_type,
|
2470
2582
|
args: args,
|
2471
2583
|
arg_pairs: arg_pairs,
|
2472
2584
|
block_params: block_params,
|
2473
2585
|
block_body: block_body,
|
2474
|
-
child_typing: child_typing,
|
2475
2586
|
topdown_hint: topdown_hint
|
2476
2587
|
)
|
2477
|
-
|
2478
|
-
raise unless ret.is_a?(Array) && ret[1].is_a?(TypeConstruction)
|
2479
|
-
|
2480
|
-
result, constr = ret
|
2481
|
-
|
2482
|
-
[result, constr, method_type]
|
2483
2588
|
end
|
2484
2589
|
end
|
2485
2590
|
end
|
2486
2591
|
end
|
2487
2592
|
|
2488
|
-
|
2489
|
-
|
2490
|
-
else
|
2593
|
+
case
|
2594
|
+
when results.empty?
|
2491
2595
|
method_type = method.method_types.last
|
2596
|
+
all_decls = method.method_types.each.with_object(Set[]) do |method_type, set|
|
2597
|
+
set.merge(method_type.method_decls)
|
2598
|
+
end
|
2599
|
+
error = Errors::IncompatibleArguments.new(node: node, receiver_type: receiver_type, method_type: method_type)
|
2600
|
+
call = TypeInference::MethodCall::Error.new(
|
2601
|
+
node: node,
|
2602
|
+
context: context.method_context,
|
2603
|
+
method_name: method_name,
|
2604
|
+
receiver_type: receiver_type,
|
2605
|
+
return_type: method_type.return_type,
|
2606
|
+
errors: [error],
|
2607
|
+
method_decls: all_decls
|
2608
|
+
)
|
2492
2609
|
constr = self.with_new_typing(typing.new_child(node_range))
|
2493
|
-
|
2494
|
-
|
2495
|
-
|
2496
|
-
|
2497
|
-
|
2498
|
-
when Errors::Base
|
2499
|
-
if method.method_types.size == 1
|
2500
|
-
typing.add_error result
|
2501
|
-
type = case method_type.return_type
|
2502
|
-
when AST::Types::Var
|
2503
|
-
AST::Builtin.any_type
|
2504
|
-
else
|
2505
|
-
method_type.return_type
|
2506
|
-
end
|
2610
|
+
when (call, constr = results.find {|call, _| call.is_a?(TypeInference::MethodCall::Typed) })
|
2611
|
+
# Nop
|
2612
|
+
else
|
2613
|
+
if results.one?
|
2614
|
+
call, constr = results[0]
|
2507
2615
|
else
|
2508
|
-
|
2509
|
-
receiver_type: expand_self(receiver_type),
|
2510
|
-
method_name: method_name,
|
2511
|
-
method_types: method.method_types)
|
2512
|
-
type = AST::Builtin.any_type
|
2616
|
+
return
|
2513
2617
|
end
|
2514
|
-
|
2515
|
-
[type,
|
2516
|
-
update_lvar_env { constr.context.lvar_env },
|
2517
|
-
result]
|
2518
|
-
else # Type
|
2519
|
-
[result,
|
2520
|
-
update_lvar_env { constr.context.lvar_env },
|
2521
|
-
nil]
|
2522
2618
|
end
|
2619
|
+
constr.typing.save!
|
2620
|
+
|
2621
|
+
[
|
2622
|
+
call,
|
2623
|
+
update_lvar_env { constr.context.lvar_env }
|
2624
|
+
]
|
2523
2625
|
end
|
2524
2626
|
|
2525
2627
|
def check_keyword_arg(receiver_type:, node:, method_type:, constraints:)
|
@@ -2621,14 +2723,12 @@ module Steep
|
|
2621
2723
|
|
2622
2724
|
hash_type = AST::Builtin::Hash.instance_type(
|
2623
2725
|
AST::Builtin::Symbol.instance_type,
|
2624
|
-
AST::Types::Union.build(types: value_types
|
2625
|
-
location: method_type.location)
|
2726
|
+
AST::Types::Union.build(types: value_types)
|
2626
2727
|
)
|
2627
2728
|
else
|
2628
2729
|
hash_elements = params.required_keywords.merge(
|
2629
2730
|
method_type.params.optional_keywords.transform_values do |type|
|
2630
|
-
AST::Types::Union.build(types: [type, AST::Builtin.nil_type]
|
2631
|
-
location: method_type.location)
|
2731
|
+
AST::Types::Union.build(types: [type, AST::Builtin.nil_type])
|
2632
2732
|
end
|
2633
2733
|
)
|
2634
2734
|
|
@@ -2650,151 +2750,211 @@ module Steep
|
|
2650
2750
|
nil
|
2651
2751
|
end
|
2652
2752
|
|
2653
|
-
def try_method_type(node, receiver_type:, method_type:, args:, arg_pairs:, block_params:, block_body:,
|
2753
|
+
def try_method_type(node, receiver_type:, method_name:, method_type:, args:, arg_pairs:, block_params:, block_body:, topdown_hint:)
|
2654
2754
|
fresh_types = method_type.type_params.map {|x| AST::Types::Var.fresh(x)}
|
2655
2755
|
fresh_vars = Set.new(fresh_types.map(&:name))
|
2656
2756
|
instantiation = Interface::Substitution.build(method_type.type_params, fresh_types)
|
2657
2757
|
|
2658
|
-
|
2659
|
-
checker: checker,
|
2660
|
-
source: source,
|
2661
|
-
annotations: annotations,
|
2662
|
-
typing: child_typing,
|
2663
|
-
context: context
|
2664
|
-
)
|
2758
|
+
constr = self
|
2665
2759
|
|
2666
|
-
|
2760
|
+
method_type = method_type.instantiate(instantiation)
|
2667
2761
|
|
2668
|
-
|
2669
|
-
|
2670
|
-
|
2671
|
-
occurence = Subtyping::VariableOccurence.from_method_type(method_type)
|
2762
|
+
constraints = Subtyping::Constraints.new(unknowns: fresh_types.map(&:name))
|
2763
|
+
variance = Subtyping::VariableVariance.from_method_type(method_type)
|
2764
|
+
occurence = Subtyping::VariableOccurence.from_method_type(method_type)
|
2672
2765
|
|
2673
|
-
|
2674
|
-
case pair
|
2675
|
-
when Array
|
2676
|
-
(arg_node, param_type) = pair
|
2677
|
-
param_type = param_type.subst(instantiation)
|
2766
|
+
errors = []
|
2678
2767
|
|
2679
|
-
|
2680
|
-
|
2681
|
-
|
2682
|
-
|
2683
|
-
|
2768
|
+
arg_pairs.each do |pair|
|
2769
|
+
case pair
|
2770
|
+
when Array
|
2771
|
+
arg_node, param_type = pair
|
2772
|
+
param_type = param_type.subst(instantiation)
|
2684
2773
|
|
2685
|
-
|
2686
|
-
|
2774
|
+
arg_type, constr = if arg_node.type == :splat
|
2775
|
+
constr.synthesize(arg_node.children[0])
|
2776
|
+
else
|
2777
|
+
constr.synthesize(arg_node, hint: topdown_hint ? param_type : nil)
|
2778
|
+
end
|
2779
|
+
|
2780
|
+
check_relation(sub_type: arg_type, super_type: param_type, constraints: constraints).else do
|
2781
|
+
errors << Errors::ArgumentTypeMismatch.new(node: arg_node,
|
2687
2782
|
receiver_type: receiver_type,
|
2688
2783
|
expected: param_type,
|
2689
|
-
actual: arg_type)
|
2690
|
-
|
2691
|
-
|
2692
|
-
|
2693
|
-
|
2694
|
-
|
2695
|
-
|
2696
|
-
|
2697
|
-
constraints: constraints)
|
2784
|
+
actual: arg_type)
|
2785
|
+
end
|
2786
|
+
else
|
2787
|
+
# keyword
|
2788
|
+
result = constr.check_keyword_arg(receiver_type: receiver_type,
|
2789
|
+
node: pair,
|
2790
|
+
method_type: method_type,
|
2791
|
+
constraints: constraints)
|
2698
2792
|
|
2699
|
-
|
2700
|
-
|
2701
|
-
end
|
2793
|
+
if result.is_a?(Errors::Base)
|
2794
|
+
errors << result
|
2702
2795
|
end
|
2703
2796
|
end
|
2797
|
+
end
|
2704
2798
|
|
2705
|
-
|
2706
|
-
|
2707
|
-
|
2708
|
-
|
2709
|
-
|
2710
|
-
|
2711
|
-
|
2712
|
-
|
2713
|
-
|
2714
|
-
|
2715
|
-
constr
|
2716
|
-
|
2717
|
-
|
2718
|
-
|
2719
|
-
|
2720
|
-
|
2721
|
-
|
2722
|
-
|
2723
|
-
|
2724
|
-
|
2725
|
-
|
2726
|
-
|
2727
|
-
|
2728
|
-
|
2729
|
-
|
2730
|
-
|
2731
|
-
|
2732
|
-
|
2733
|
-
|
2734
|
-
|
2735
|
-
|
2736
|
-
|
2737
|
-
|
2738
|
-
|
2739
|
-
|
2799
|
+
if block_params
|
2800
|
+
# block is given
|
2801
|
+
block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
|
2802
|
+
block_params_ = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
|
2803
|
+
|
2804
|
+
if method_type.block
|
2805
|
+
pairs = method_type.block && block_params_&.zip(method_type.block.type.params)
|
2806
|
+
|
2807
|
+
if pairs
|
2808
|
+
begin
|
2809
|
+
block_constr = constr.for_block(
|
2810
|
+
block_params: block_params_,
|
2811
|
+
block_param_hint: method_type.block.type.params,
|
2812
|
+
block_annotations: block_annotations,
|
2813
|
+
node_type_hint: method_type.return_type
|
2814
|
+
)
|
2815
|
+
block_constr = block_constr.with_new_typing(
|
2816
|
+
block_constr.typing.new_child(
|
2817
|
+
range: block_constr.typing.block_range(node)
|
2818
|
+
)
|
2819
|
+
)
|
2820
|
+
|
2821
|
+
block_constr.typing.add_context_for_body(node, context: block_constr.context)
|
2822
|
+
|
2823
|
+
pairs.each do |param, type|
|
2824
|
+
_, block_constr = block_constr.synthesize(param.node, hint: param.type || type)
|
2825
|
+
|
2826
|
+
if param.type
|
2827
|
+
check_relation(sub_type: type, super_type: param.type, constraints: constraints).else do |result|
|
2828
|
+
error = Errors::IncompatibleAssignment.new(
|
2829
|
+
node: param.node,
|
2830
|
+
lhs_type: param.type,
|
2831
|
+
rhs_type: type,
|
2832
|
+
result: result
|
2833
|
+
)
|
2834
|
+
errors << error
|
2835
|
+
end
|
2836
|
+
end
|
2740
2837
|
end
|
2741
|
-
end
|
2742
|
-
end
|
2743
|
-
end
|
2744
2838
|
|
2745
|
-
|
2746
|
-
|
2747
|
-
|
2748
|
-
|
2749
|
-
|
2750
|
-
|
2751
|
-
|
2752
|
-
|
2753
|
-
|
2754
|
-
|
2755
|
-
|
2756
|
-
|
2757
|
-
|
2758
|
-
|
2759
|
-
|
2760
|
-
|
2761
|
-
|
2839
|
+
s = constraints.solution(
|
2840
|
+
checker,
|
2841
|
+
self_type: self_type,
|
2842
|
+
variance: variance,
|
2843
|
+
variables: method_type.params.free_variables + method_type.block.type.params.free_variables
|
2844
|
+
)
|
2845
|
+
method_type = method_type.subst(s)
|
2846
|
+
block_constr = block_constr.update_lvar_env {|env| env.subst(s) }
|
2847
|
+
if block_body
|
2848
|
+
block_body_type = block_constr.synthesize_block(
|
2849
|
+
node: node,
|
2850
|
+
block_type_hint: method_type.block.type.return_type,
|
2851
|
+
block_body: block_body,
|
2852
|
+
topdown_hint: topdown_hint
|
2853
|
+
) do |error|
|
2854
|
+
errors << error
|
2855
|
+
end
|
2856
|
+
else
|
2857
|
+
block_body_type = AST::Builtin.nil_type
|
2858
|
+
end
|
2859
|
+
|
2860
|
+
result = check_relation(sub_type: block_body_type,
|
2762
2861
|
super_type: method_type.block.type.return_type,
|
2763
2862
|
constraints: constraints)
|
2764
2863
|
|
2765
2864
|
case result
|
2766
2865
|
when Subtyping::Result::Success
|
2767
|
-
|
2768
|
-
|
2769
|
-
|
2770
|
-
|
2771
|
-
|
2772
|
-
|
2773
|
-
[ty, constr]
|
2866
|
+
s = constraints.solution(checker, self_type: self_type, variance: variance, variables: fresh_vars)
|
2867
|
+
method_type = method_type.subst(s)
|
2868
|
+
|
2869
|
+
return_type = method_type.return_type
|
2870
|
+
if break_type = block_annotations.break_type
|
2871
|
+
return_type = union_type(break_type, return_type)
|
2774
2872
|
end
|
2775
2873
|
|
2776
2874
|
when Subtyping::Result::Failure
|
2777
|
-
|
2778
|
-
|
2779
|
-
|
2780
|
-
|
2781
|
-
|
2875
|
+
block_type = AST::Types::Proc.new(
|
2876
|
+
params: method_type.block.type.params || block_params.params_type,
|
2877
|
+
return_type: block_body_type
|
2878
|
+
)
|
2879
|
+
errors << Errors::BlockTypeMismatch.new(node: node,
|
2880
|
+
expected: method_type.block.type,
|
2881
|
+
actual: block_type,
|
2882
|
+
result: result)
|
2883
|
+
|
2884
|
+
return_type = method_type.return_type
|
2782
2885
|
end
|
2886
|
+
|
2887
|
+
block_constr.typing.save!
|
2888
|
+
rescue Subtyping::Constraints::UnsatisfiableConstraint => exn
|
2889
|
+
errors << Errors::UnsatisfiableConstraint.new(
|
2890
|
+
node: node,
|
2891
|
+
method_type: method_type,
|
2892
|
+
var: exn.var,
|
2893
|
+
sub_type: exn.sub_type,
|
2894
|
+
super_type: exn.super_type,
|
2895
|
+
result: exn.result
|
2896
|
+
)
|
2897
|
+
|
2898
|
+
constr.type_block_without_hint(node: node, block_annotations: block_annotations, block_params: block_params_, block_body: block_body) do |error|
|
2899
|
+
errors << error
|
2900
|
+
end
|
2901
|
+
|
2902
|
+
s = Interface::Substitution.build(method_type.free_variables,
|
2903
|
+
Array.new(method_type.free_variables.size, AST::Builtin.any_type))
|
2904
|
+
method_type = method_type.subst(s)
|
2783
2905
|
end
|
2906
|
+
else
|
2907
|
+
errors << Errors::UnsupportedSyntax.new(
|
2908
|
+
node: block_params,
|
2909
|
+
message: "Unsupported block params pattern, probably masgn?"
|
2910
|
+
)
|
2911
|
+
|
2912
|
+
s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
|
2913
|
+
method_type = method_type.subst(s)
|
2914
|
+
end
|
2915
|
+
else
|
2916
|
+
# Block is given but method doesn't accept
|
2917
|
+
#
|
2918
|
+
constr.type_block_without_hint(node: node, block_annotations: block_annotations, block_params: block_params_, block_body: block_body) do |error|
|
2919
|
+
errors << error
|
2920
|
+
end
|
2784
2921
|
|
2785
|
-
|
2786
|
-
|
2787
|
-
|
2788
|
-
|
2789
|
-
|
2790
|
-
|
2791
|
-
|
2792
|
-
|
2922
|
+
errors << Errors::UnexpectedBlockGiven.new(
|
2923
|
+
node: node,
|
2924
|
+
method_type: method_type
|
2925
|
+
)
|
2926
|
+
end
|
2927
|
+
else
|
2928
|
+
# block is not given
|
2929
|
+
if (!method_type.block || method_type.block.optional?)
|
2930
|
+
# Method call without block is allowed
|
2931
|
+
unless args.block_pass_arg
|
2932
|
+
# OK, without block
|
2933
|
+
s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
|
2934
|
+
method_type = method_type.subst(s)
|
2935
|
+
else
|
2936
|
+
# &block arg is given
|
2937
|
+
s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
|
2938
|
+
method_type = method_type.subst(s)
|
2939
|
+
|
2940
|
+
errors << Errors::UnexpectedBlockGiven.new(
|
2941
|
+
node: node,
|
2942
|
+
method_type: method_type
|
2943
|
+
)
|
2793
2944
|
end
|
2945
|
+
else
|
2946
|
+
unless args.block_pass_arg
|
2947
|
+
# Required block is missing
|
2948
|
+
errors << Errors::RequiredBlockMissing.new(
|
2949
|
+
node: node,
|
2950
|
+
method_type: method_type
|
2951
|
+
)
|
2794
2952
|
|
2795
|
-
|
2796
|
-
|
2797
|
-
|
2953
|
+
s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
|
2954
|
+
method_type = method_type.subst(s)
|
2955
|
+
else
|
2956
|
+
begin
|
2957
|
+
method_type = method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: occurence.params))
|
2798
2958
|
block_type, constr = constr.synthesize(args.block_pass_arg, hint: topdown_hint ? method_type.block.type : nil)
|
2799
2959
|
result = check_relation(
|
2800
2960
|
sub_type: block_type,
|
@@ -2808,68 +2968,65 @@ module Steep
|
|
2808
2968
|
constraints: constraints
|
2809
2969
|
)
|
2810
2970
|
|
2811
|
-
|
2812
|
-
|
2813
|
-
|
2814
|
-
|
2815
|
-
|
2816
|
-
]
|
2817
|
-
|
2818
|
-
when Subtyping::Result::Failure
|
2819
|
-
[
|
2820
|
-
Errors::BlockTypeMismatch.new(node: node,
|
2821
|
-
expected: method_type.block.type,
|
2822
|
-
actual: block_type,
|
2823
|
-
result: result),
|
2824
|
-
constr
|
2825
|
-
]
|
2971
|
+
result.else do |result|
|
2972
|
+
errors << Errors::BlockTypeMismatch.new(node: node,
|
2973
|
+
expected: method_type.block.type,
|
2974
|
+
actual: block_type,
|
2975
|
+
result: result)
|
2826
2976
|
end
|
2977
|
+
|
2978
|
+
method_type = method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: method_type.free_variables))
|
2827
2979
|
end
|
2980
|
+
end
|
2981
|
+
end
|
2982
|
+
end
|
2828
2983
|
|
2829
|
-
|
2830
|
-
|
2831
|
-
|
2832
|
-
|
2833
|
-
|
2834
|
-
|
2835
|
-
|
2836
|
-
|
2837
|
-
|
2838
|
-
|
2839
|
-
|
2840
|
-
|
2841
|
-
|
2842
|
-
|
2843
|
-
|
2844
|
-
|
2845
|
-
|
2846
|
-
|
2847
|
-
|
2848
|
-
|
2849
|
-
|
2850
|
-
|
2851
|
-
|
2852
|
-
|
2853
|
-
|
2854
|
-
|
2855
|
-
|
2984
|
+
call = if errors.empty?
|
2985
|
+
TypeInference::MethodCall::Typed.new(
|
2986
|
+
node: node,
|
2987
|
+
context: context.method_context,
|
2988
|
+
receiver_type: receiver_type,
|
2989
|
+
method_name: method_name,
|
2990
|
+
actual_method_type: method_type,
|
2991
|
+
return_type: return_type || method_type.return_type,
|
2992
|
+
method_decls: method_type.method_decls
|
2993
|
+
)
|
2994
|
+
else
|
2995
|
+
TypeInference::MethodCall::Error.new(
|
2996
|
+
node: node,
|
2997
|
+
context: context.method_context,
|
2998
|
+
receiver_type: receiver_type,
|
2999
|
+
method_name: method_name,
|
3000
|
+
return_type: return_type || method_type.return_type,
|
3001
|
+
method_decls: method_type.method_decls,
|
3002
|
+
errors: errors
|
3003
|
+
)
|
3004
|
+
end
|
3005
|
+
|
3006
|
+
[
|
3007
|
+
call,
|
3008
|
+
constr
|
3009
|
+
]
|
3010
|
+
end
|
3011
|
+
|
3012
|
+
def type_block_without_hint(node:, block_annotations:, block_params:, block_body:, &block)
|
3013
|
+
block_constr = for_block(
|
3014
|
+
block_params: block_params,
|
3015
|
+
block_param_hint: nil,
|
3016
|
+
block_annotations: block_annotations,
|
3017
|
+
node_type_hint: nil
|
3018
|
+
)
|
2856
3019
|
|
2857
|
-
|
2858
|
-
[
|
2859
|
-
Errors::RequiredBlockMissing.new(
|
2860
|
-
node: node,
|
2861
|
-
method_type: method_type
|
2862
|
-
),
|
2863
|
-
constr
|
2864
|
-
]
|
3020
|
+
block_constr.typing.add_context_for_body(node, context: block_constr.context)
|
2865
3021
|
|
2866
|
-
|
2867
|
-
|
2868
|
-
end
|
3022
|
+
block_params.params.each do |param|
|
3023
|
+
_, block_constr = block_constr.synthesize(param.node, hint: param.type)
|
2869
3024
|
end
|
3025
|
+
|
3026
|
+
block_constr.synthesize_block(node: node, block_type_hint: nil, block_body: block_body, topdown_hint: false, &block)
|
2870
3027
|
end
|
2871
3028
|
|
2872
|
-
def
|
3029
|
+
def for_block(block_params:, block_param_hint:, block_annotations:, node_type_hint:)
|
2873
3030
|
block_param_pairs = block_param_hint && block_params.zip(block_param_hint)
|
2874
3031
|
|
2875
3032
|
param_types_hash = {}
|
@@ -2885,30 +3042,30 @@ module Steep
|
|
2885
3042
|
end
|
2886
3043
|
end
|
2887
3044
|
|
2888
|
-
|
2889
|
-
|
2890
|
-
|
2891
|
-
|
2892
|
-
|
2893
|
-
|
3045
|
+
decls = param_types_hash.each.with_object({}) do |(name, type), hash|
|
3046
|
+
hash[name] = TypeInference::LocalVariableTypeEnv::Entry.new(type: type)
|
3047
|
+
end
|
3048
|
+
lvar_env = context.lvar_env
|
3049
|
+
.pin_assignments
|
3050
|
+
.except(decls.keys)
|
3051
|
+
.update(assigned_types: decls)
|
3052
|
+
.annotate(block_annotations)
|
2894
3053
|
|
2895
3054
|
break_type = if block_annotations.break_type
|
2896
3055
|
union_type(node_type_hint, block_annotations.break_type)
|
2897
3056
|
else
|
2898
3057
|
node_type_hint
|
2899
3058
|
end
|
2900
|
-
Steep.logger.debug("return_type = #{break_type}")
|
2901
|
-
|
2902
|
-
block_context = TypeInference::Context::BlockContext.new(body_type: block_annotations.block_type)
|
2903
|
-
Steep.logger.debug("block_context { body_type: #{block_context.body_type} }")
|
2904
3059
|
|
3060
|
+
block_context = TypeInference::Context::BlockContext.new(
|
3061
|
+
body_type: block_annotations.block_type
|
3062
|
+
)
|
2905
3063
|
break_context = TypeInference::Context::BreakContext.new(
|
2906
3064
|
break_type: break_type,
|
2907
3065
|
next_type: block_context.body_type
|
2908
3066
|
)
|
2909
|
-
Steep.logger.debug("break_context { type: #{break_context.break_type} }")
|
2910
3067
|
|
2911
|
-
|
3068
|
+
self.class.new(
|
2912
3069
|
checker: checker,
|
2913
3070
|
source: source,
|
2914
3071
|
annotations: annotations.merge_block_annotations(block_annotations),
|
@@ -2920,37 +3077,34 @@ module Steep
|
|
2920
3077
|
break_context: break_context,
|
2921
3078
|
self_type: block_annotations.self_type || self_type,
|
2922
3079
|
type_env: type_env.dup,
|
2923
|
-
lvar_env: lvar_env
|
3080
|
+
lvar_env: lvar_env,
|
3081
|
+
call_context: self.context.call_context
|
2924
3082
|
)
|
2925
3083
|
)
|
3084
|
+
end
|
2926
3085
|
|
2927
|
-
|
2928
|
-
|
3086
|
+
def synthesize_block(node:, block_type_hint:, block_body:, topdown_hint:)
|
2929
3087
|
if block_body
|
2930
|
-
|
2931
|
-
|
2932
|
-
|
2933
|
-
|
2934
|
-
|
2935
|
-
|
2936
|
-
|
2937
|
-
|
2938
|
-
|
2939
|
-
|
2940
|
-
|
3088
|
+
body_type, _, context =
|
3089
|
+
if (body_type = block_context.body_type)
|
3090
|
+
check(block_body, body_type) do |expected, actual, result|
|
3091
|
+
error = Errors::BlockTypeMismatch.new(node: block_body,
|
3092
|
+
expected: expected,
|
3093
|
+
actual: actual,
|
3094
|
+
result: result)
|
3095
|
+
yield(error) if block_given?
|
3096
|
+
end
|
3097
|
+
else
|
3098
|
+
synthesize(block_body, hint: topdown_hint ? block_type_hint : nil)
|
3099
|
+
end
|
2941
3100
|
|
2942
3101
|
range = block_body.loc.expression.end_pos..node.loc.end.begin_pos
|
2943
|
-
typing.add_context(range, context:
|
3102
|
+
typing.add_context(range, context: context)
|
3103
|
+
|
3104
|
+
body_type
|
2944
3105
|
else
|
2945
|
-
|
3106
|
+
AST::Builtin.nil_type
|
2946
3107
|
end
|
2947
|
-
|
2948
|
-
body_pair.with(
|
2949
|
-
type: AST::Types::Proc.new(
|
2950
|
-
params: block_param_hint || block_params.params_type,
|
2951
|
-
return_type: body_pair.type
|
2952
|
-
)
|
2953
|
-
)
|
2954
3108
|
end
|
2955
3109
|
|
2956
3110
|
def each_child_node(node)
|
@@ -3172,6 +3326,14 @@ module Steep
|
|
3172
3326
|
!nodes.empty? && nodes.all? {|child| child.type == :class || child.type == :module}
|
3173
3327
|
end
|
3174
3328
|
|
3329
|
+
def type_any_rec(node)
|
3330
|
+
add_typing node, type: AST::Builtin.any_type
|
3331
|
+
|
3332
|
+
each_child_node(node) do |child|
|
3333
|
+
type_any_rec(child)
|
3334
|
+
end
|
3335
|
+
end
|
3336
|
+
|
3175
3337
|
def fallback_any_rec(node)
|
3176
3338
|
fallback_to_any(node) unless typing.has_type?(node)
|
3177
3339
|
|