steep 1.4.0.dev.2 → 1.4.0.dev.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +1 -2
- data/Gemfile +1 -1
- data/Gemfile.lock +7 -9
- data/Gemfile.steep +1 -2
- data/Gemfile.steep.lock +9 -10
- data/README.md +7 -1
- data/Steepfile +0 -3
- data/bin/rbs +0 -1
- data/guides/README.md +5 -0
- data/guides/src/gem-rbs-collection/gem-rbs-collection.md +143 -0
- data/guides/src/getting-started/getting-started.md +164 -0
- data/guides/src/nil-optional/nil-optional.md +195 -0
- data/lib/steep/diagnostic/ruby.rb +79 -4
- data/lib/steep/drivers/check.rb +4 -4
- data/lib/steep/interface/block.rb +10 -0
- data/lib/steep/module_helper.rb +13 -11
- data/lib/steep/path_helper.rb +4 -0
- data/lib/steep/server/interaction_worker.rb +105 -92
- data/lib/steep/services/type_name_completion.rb +157 -0
- data/lib/steep/source.rb +1 -0
- data/lib/steep/type_construction.rb +402 -229
- data/lib/steep/type_inference/block_params.rb +13 -0
- data/lib/steep/type_inference/context.rb +3 -3
- data/lib/steep/type_inference/method_params.rb +42 -16
- data/lib/steep/type_inference/send_args.rb +79 -50
- data/lib/steep/type_inference/type_env.rb +7 -1
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +1 -0
- data/rbs_collection.steep.lock.yaml +0 -28
- data/rbs_collection.steep.yaml +10 -9
- data/sample/lib/conference.rb +12 -0
- data/sample/sig/conference.rbs +5 -0
- data/sig/shims/language-server_protocol.rbs +12 -0
- data/sig/shims/parser/nodes.rbs +37 -0
- data/sig/shims/parser.rbs +1 -0
- data/sig/shims/string.rbs +4 -0
- data/sig/steep/ast/types/factory.rbs +10 -8
- data/sig/steep/diagnostic/lsp_formatter.rbs +1 -1
- data/sig/steep/diagnostic/ruby.rbs +38 -2
- data/sig/steep/drivers/check.rbs +1 -1
- data/sig/steep/drivers/checkfile.rbs +1 -1
- data/sig/steep/drivers/diagnostic_printer.rbs +1 -1
- data/sig/steep/drivers/watch.rbs +1 -1
- data/sig/steep/index/signature_symbol_provider.rbs +1 -1
- data/sig/steep/interface/block.rbs +2 -0
- data/sig/steep/interface/builder.rbs +5 -3
- data/sig/steep/interface/method_type.rbs +5 -3
- data/sig/steep/module_helper.rbs +9 -0
- data/sig/steep/path_helper.rbs +3 -1
- data/sig/steep/server/base_worker.rbs +1 -1
- data/sig/steep/server/interaction_worker.rbs +46 -17
- data/sig/steep/server/master.rbs +1 -1
- data/sig/steep/server/type_check_worker.rbs +7 -5
- data/sig/steep/server/worker_process.rbs +6 -4
- data/sig/steep/services/completion_provider.rbs +2 -0
- data/sig/steep/services/type_name_completion.rbs +122 -0
- data/sig/steep/type_construction.rbs +99 -30
- data/sig/steep/type_inference/block_params.rbs +4 -0
- data/sig/steep/type_inference/context.rbs +70 -22
- data/sig/steep/type_inference/method_params.rbs +43 -24
- data/sig/steep/type_inference/multiple_assignment.rbs +1 -1
- data/sig/steep/type_inference/send_args.rbs +13 -3
- data/sig/steep/typing.rbs +7 -2
- data/smoke/diagnostics/test_expectations.yml +1 -0
- data/steep.gemspec +0 -1
- metadata +10 -16
@@ -52,10 +52,6 @@ module Steep
|
|
52
52
|
context.module_context
|
53
53
|
end
|
54
54
|
|
55
|
-
def module_context!
|
56
|
-
module_context or raise
|
57
|
-
end
|
58
|
-
|
59
55
|
def method_context
|
60
56
|
context.method_context
|
61
57
|
end
|
@@ -68,6 +64,10 @@ module Steep
|
|
68
64
|
context.block_context
|
69
65
|
end
|
70
66
|
|
67
|
+
def block_context!
|
68
|
+
block_context or raise
|
69
|
+
end
|
70
|
+
|
71
71
|
def break_context
|
72
72
|
context.break_context
|
73
73
|
end
|
@@ -135,8 +135,8 @@ module Steep
|
|
135
135
|
checker.check(
|
136
136
|
relation,
|
137
137
|
self_type: self_type,
|
138
|
-
instance_type: module_context
|
139
|
-
class_type: module_context
|
138
|
+
instance_type: module_context.instance_type,
|
139
|
+
class_type: module_context.module_type,
|
140
140
|
constraints: constraints
|
141
141
|
)
|
142
142
|
end
|
@@ -163,8 +163,8 @@ module Steep
|
|
163
163
|
|
164
164
|
method_type = annotation_method_type || definition_method_type
|
165
165
|
|
166
|
-
if annots&.return_type && method_type&.type&.return_type
|
167
|
-
check_relation(sub_type:
|
166
|
+
if (annotation_return_type = annots&.return_type) && (method_type_return_type = method_type&.type&.return_type)
|
167
|
+
check_relation(sub_type: annotation_return_type, super_type: method_type_return_type).else do |result|
|
168
168
|
typing.add_error(
|
169
169
|
Diagnostic::Ruby::MethodReturnTypeAnnotationMismatch.new(
|
170
170
|
node: node,
|
@@ -194,23 +194,23 @@ module Steep
|
|
194
194
|
variable_context = self.variable_context
|
195
195
|
end
|
196
196
|
|
197
|
+
method_params =
|
198
|
+
if method_type
|
199
|
+
TypeInference::MethodParams.build(node: node, method_type: method_type)
|
200
|
+
else
|
201
|
+
TypeInference::MethodParams.empty(node: node)
|
202
|
+
end
|
203
|
+
|
197
204
|
method_context = TypeInference::Context::MethodContext.new(
|
198
205
|
name: method_name,
|
199
206
|
method: definition && definition.methods[method_name],
|
200
207
|
method_type: method_type,
|
201
208
|
return_type: annots.return_type || method_type&.type&.return_type || AST::Builtin.any_type,
|
202
|
-
|
203
|
-
|
209
|
+
super_method: super_method,
|
210
|
+
forward_arg_type: method_params.forward_arg_type
|
204
211
|
)
|
205
212
|
|
206
|
-
method_params
|
207
|
-
if method_type
|
208
|
-
TypeInference::MethodParams.build(node: node, method_type: method_type)
|
209
|
-
else
|
210
|
-
TypeInference::MethodParams.empty(node: node)
|
211
|
-
end
|
212
|
-
|
213
|
-
local_variable_types = method_params.each_param.with_object({}) do |param, hash|
|
213
|
+
local_variable_types = method_params.each_param.with_object({}) do |param, hash| #$ Hash[Symbol, AST::Types::t]
|
214
214
|
if param.name
|
215
215
|
unless SPECIAL_LVAR_NAMES.include?(param.name)
|
216
216
|
hash[param.name] = param.var_type
|
@@ -221,14 +221,16 @@ module Steep
|
|
221
221
|
|
222
222
|
type_env = TypeInference::TypeEnvBuilder.new(
|
223
223
|
TypeInference::TypeEnvBuilder::Command::ImportLocalVariableAnnotations.new(annots).merge!.on_duplicate! do |name, original, annotated|
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
224
|
+
if method_params.param?(name)
|
225
|
+
param = method_params[name]
|
226
|
+
if result = no_subtyping?(sub_type: original, super_type: annotated)
|
227
|
+
typing.add_error Diagnostic::Ruby::IncompatibleAnnotation.new(
|
228
|
+
node: param.node,
|
229
|
+
var_name: name,
|
230
|
+
result: result,
|
231
|
+
relation: result.relation
|
232
|
+
)
|
233
|
+
end
|
232
234
|
end
|
233
235
|
end,
|
234
236
|
TypeInference::TypeEnvBuilder::Command::ImportInstanceVariableDefinition.new(definition, checker.factory),
|
@@ -308,7 +310,7 @@ module Steep
|
|
308
310
|
|
309
311
|
def default_module_context(implement_module_name, nesting:)
|
310
312
|
if implement_module_name
|
311
|
-
module_name = checker.factory.absolute_type_name(implement_module_name.name, context: nesting)
|
313
|
+
module_name = checker.factory.absolute_type_name(implement_module_name.name, context: nesting) or raise
|
312
314
|
module_args = implement_module_name.args.map {|name| AST::Types::Var.new(name: name) }
|
313
315
|
|
314
316
|
instance_def = checker.factory.definition_builder.build_instance(module_name)
|
@@ -328,8 +330,8 @@ module Steep
|
|
328
330
|
)
|
329
331
|
else
|
330
332
|
TypeInference::Context::ModuleContext.new(
|
331
|
-
instance_type:
|
332
|
-
module_type:
|
333
|
+
instance_type: AST::Builtin::Object.instance_type,
|
334
|
+
module_type: AST::Builtin::Object.module_type,
|
333
335
|
implement_name: nil,
|
334
336
|
nesting: nesting,
|
335
337
|
class_name: self.module_context.class_name,
|
@@ -375,6 +377,8 @@ module Steep
|
|
375
377
|
args: module_self.args,
|
376
378
|
location: module_self.location
|
377
379
|
)
|
380
|
+
else
|
381
|
+
raise
|
378
382
|
end
|
379
383
|
checker.factory.type(type)
|
380
384
|
},
|
@@ -451,7 +455,7 @@ module Steep
|
|
451
455
|
end
|
452
456
|
|
453
457
|
def for_class(node, new_class_name, super_class_name)
|
454
|
-
new_nesting = [nesting, new_class_name || false]
|
458
|
+
new_nesting = [nesting, new_class_name || false] #: RBS::Resolver::context
|
455
459
|
annots = source.annotations(block: node, factory: checker.factory, context: new_nesting)
|
456
460
|
|
457
461
|
class_const_env = TypeInference::ConstantEnv.new(
|
@@ -594,7 +598,7 @@ module Steep
|
|
594
598
|
|
595
599
|
module_definition = case module_type
|
596
600
|
when AST::Types::Name::Singleton
|
597
|
-
type_name =
|
601
|
+
type_name = module_type.name
|
598
602
|
checker.factory.definition_builder.build_singleton(type_name)
|
599
603
|
else
|
600
604
|
nil
|
@@ -728,7 +732,7 @@ module Steep
|
|
728
732
|
else
|
729
733
|
if enforced_type = context.type_env.enforced_type(name)
|
730
734
|
case
|
731
|
-
when hint
|
735
|
+
when !hint
|
732
736
|
hint = enforced_type
|
733
737
|
when check_relation(sub_type: enforced_type, super_type: hint).success?
|
734
738
|
# enforced_type is compatible with hint and more specific to hint.
|
@@ -862,27 +866,29 @@ module Steep
|
|
862
866
|
|
863
867
|
when :super
|
864
868
|
yield_self do
|
865
|
-
if self_type && method_context
|
866
|
-
if super_def = method_context
|
869
|
+
if self_type && method_context!.method
|
870
|
+
if super_def = method_context!.super_method
|
867
871
|
each_child_node(node) do |child|
|
868
872
|
synthesize(child)
|
869
873
|
end
|
870
874
|
|
871
875
|
super_method = Interface::Shape::Entry.new(
|
872
|
-
method_types:
|
876
|
+
method_types: super_def.defs.map {|type_def|
|
873
877
|
decl = TypeInference::MethodCall::MethodDecl.new(
|
874
|
-
method_name: InstanceMethodName.new(
|
875
|
-
|
876
|
-
|
878
|
+
method_name: InstanceMethodName.new(
|
879
|
+
type_name: super_def.implemented_in || super_def.defined_in || raise,
|
880
|
+
method_name: method_context!.name || raise("method context must have a name")
|
881
|
+
),
|
882
|
+
method_def: type_def
|
877
883
|
)
|
878
|
-
checker.factory.method_type(
|
884
|
+
checker.factory.method_type(type_def.type, method_decls: Set[decl])
|
879
885
|
}
|
880
886
|
)
|
881
887
|
|
882
888
|
call, constr = type_method_call(
|
883
889
|
node,
|
884
890
|
receiver_type: self_type,
|
885
|
-
method_name: method_context
|
891
|
+
method_name: method_context!.name || raise("method context must have a name"),
|
886
892
|
method: super_method,
|
887
893
|
arguments: node.children,
|
888
894
|
block_params: nil,
|
@@ -896,13 +902,13 @@ module Steep
|
|
896
902
|
error = Diagnostic::Ruby::UnresolvedOverloading.new(
|
897
903
|
node: node,
|
898
904
|
receiver_type: self_type,
|
899
|
-
method_name: method_context
|
905
|
+
method_name: method_context!.name,
|
900
906
|
method_types: super_method.method_types
|
901
907
|
)
|
902
908
|
call = TypeInference::MethodCall::Error.new(
|
903
909
|
node: node,
|
904
|
-
context: context.
|
905
|
-
method_name: method_context
|
910
|
+
context: context.call_context,
|
911
|
+
method_name: method_context!.name || raise("method context must have a name"),
|
906
912
|
receiver_type: self_type,
|
907
913
|
errors: [error]
|
908
914
|
)
|
@@ -913,7 +919,7 @@ module Steep
|
|
913
919
|
end
|
914
920
|
else
|
915
921
|
fallback_to_any node do
|
916
|
-
Diagnostic::Ruby::UnexpectedSuper.new(node: node, method: method_context
|
922
|
+
Diagnostic::Ruby::UnexpectedSuper.new(node: node, method: method_context!.name)
|
917
923
|
end
|
918
924
|
end
|
919
925
|
else
|
@@ -923,6 +929,8 @@ module Steep
|
|
923
929
|
|
924
930
|
when :def
|
925
931
|
yield_self do
|
932
|
+
# @type var node: Parser::AST::Node & Parser::AST::_DefNode
|
933
|
+
|
926
934
|
name, args_node, body_node = node.children
|
927
935
|
|
928
936
|
with_method_constr(
|
@@ -1021,16 +1029,16 @@ module Steep
|
|
1021
1029
|
new.typing.add_context_for_node(node, context: new.context)
|
1022
1030
|
new.typing.add_context_for_body(node, context: new.context)
|
1023
1031
|
|
1024
|
-
new.method_context
|
1032
|
+
new.method_context!.tap do |method_context|
|
1025
1033
|
if method_context.method
|
1026
1034
|
name_ = node.children[1]
|
1027
1035
|
|
1028
1036
|
method_name =
|
1029
1037
|
case self_type
|
1030
1038
|
when AST::Types::Name::Instance
|
1031
|
-
InstanceMethodName.new(type_name: method_context.method.implemented_in, method_name: name_)
|
1039
|
+
InstanceMethodName.new(type_name: method_context.method.implemented_in || raise, method_name: name_)
|
1032
1040
|
when AST::Types::Name::Singleton
|
1033
|
-
SingletonMethodName.new(type_name: method_context.method.implemented_in, method_name: name_)
|
1041
|
+
SingletonMethodName.new(type_name: method_context.method.implemented_in || raise, method_name: name_)
|
1034
1042
|
end
|
1035
1043
|
|
1036
1044
|
new.typing.source_index.add_definition(method: method_name, definition: node)
|
@@ -1044,8 +1052,8 @@ module Steep
|
|
1044
1052
|
end
|
1045
1053
|
|
1046
1054
|
if node.children[3]
|
1047
|
-
return_type = expand_alias(new.method_context
|
1048
|
-
if
|
1055
|
+
return_type = expand_alias(new.method_context!.return_type)
|
1056
|
+
if !return_type.is_a?(AST::Types::Void)
|
1049
1057
|
new.check(node.children[3], return_type) do |return_type, actual_type, result|
|
1050
1058
|
typing.add_error(
|
1051
1059
|
Diagnostic::Ruby::MethodBodyTypeMismatch.new(
|
@@ -1062,49 +1070,44 @@ module Steep
|
|
1062
1070
|
end
|
1063
1071
|
end
|
1064
1072
|
|
1065
|
-
if
|
1066
|
-
|
1067
|
-
module_context.defined_module_methods << node.children[1]
|
1068
|
-
end
|
1073
|
+
if node.children[0].type == :self
|
1074
|
+
module_context.defined_module_methods << node.children[1]
|
1069
1075
|
end
|
1070
1076
|
|
1071
1077
|
add_typing(node, type: AST::Builtin::Symbol.instance_type)
|
1072
1078
|
|
1073
1079
|
when :return
|
1074
1080
|
yield_self do
|
1075
|
-
method_return_type =
|
1081
|
+
method_return_type =
|
1082
|
+
if method_context
|
1083
|
+
expand_alias(method_context.return_type)
|
1084
|
+
end
|
1076
1085
|
|
1077
|
-
|
1086
|
+
case node.children.size
|
1087
|
+
when 0
|
1088
|
+
value_type = AST::Builtin.nil_type
|
1089
|
+
constr = self
|
1090
|
+
when 1
|
1091
|
+
return_value_node = node.children[0]
|
1092
|
+
value_type, constr = synthesize(return_value_node, hint: method_return_type)
|
1093
|
+
else
|
1094
|
+
constr = synthesize_children(node)
|
1078
1095
|
return_types = node.children.map do |value|
|
1079
|
-
|
1080
|
-
value,
|
1081
|
-
hint: if method_return_type.is_a?(AST::Types::Void)
|
1082
|
-
nil
|
1083
|
-
else
|
1084
|
-
method_return_type
|
1085
|
-
end
|
1086
|
-
).type
|
1096
|
+
constr.typing.type_of(node: value)
|
1087
1097
|
end
|
1088
1098
|
|
1089
|
-
value_type =
|
1090
|
-
return_types.first
|
1091
|
-
else
|
1092
|
-
AST::Builtin::Array.instance_type(union_type(*return_types))
|
1093
|
-
end
|
1094
|
-
|
1095
|
-
else
|
1096
|
-
value_type = AST::Builtin.nil_type
|
1099
|
+
value_type = AST::Builtin::Array.instance_type(union_type(*return_types))
|
1097
1100
|
end
|
1098
1101
|
|
1099
1102
|
if method_return_type
|
1100
|
-
unless method_return_type.is_a?(AST::Types::Void)
|
1101
|
-
result = check_relation(sub_type: value_type, super_type: method_return_type)
|
1103
|
+
unless method_context.nil? || method_return_type.is_a?(AST::Types::Void)
|
1104
|
+
result = constr.check_relation(sub_type: value_type, super_type: method_return_type)
|
1102
1105
|
|
1103
1106
|
if result.failure?
|
1104
1107
|
typing.add_error(
|
1105
1108
|
Diagnostic::Ruby::ReturnTypeMismatch.new(
|
1106
1109
|
node: node,
|
1107
|
-
expected:
|
1110
|
+
expected: method_return_type,
|
1108
1111
|
actual: value_type,
|
1109
1112
|
result: result
|
1110
1113
|
)
|
@@ -1113,14 +1116,14 @@ module Steep
|
|
1113
1116
|
end
|
1114
1117
|
end
|
1115
1118
|
|
1116
|
-
add_typing(node, type: AST::Builtin.bottom_type)
|
1119
|
+
constr.add_typing(node, type: AST::Builtin.bottom_type)
|
1117
1120
|
end
|
1118
1121
|
|
1119
1122
|
when :break
|
1120
1123
|
value = node.children[0]
|
1121
1124
|
|
1122
1125
|
if break_context
|
1123
|
-
break_type =
|
1126
|
+
break_type = break_context.break_type
|
1124
1127
|
|
1125
1128
|
if value
|
1126
1129
|
check(value, break_type) do |break_type, actual_type, result|
|
@@ -1158,7 +1161,7 @@ module Steep
|
|
1158
1161
|
|
1159
1162
|
if break_context
|
1160
1163
|
if next_type = break_context.next_type
|
1161
|
-
next_type = deep_expand_alias(next_type)
|
1164
|
+
next_type = deep_expand_alias(next_type) || next_type
|
1162
1165
|
|
1163
1166
|
if value
|
1164
1167
|
_, constr = check(value, next_type) do |break_type, actual_type, result|
|
@@ -1201,7 +1204,7 @@ module Steep
|
|
1201
1204
|
|
1202
1205
|
when :procarg0
|
1203
1206
|
yield_self do
|
1204
|
-
constr = self
|
1207
|
+
constr = self #: TypeConstruction
|
1205
1208
|
|
1206
1209
|
node.children.each do |arg|
|
1207
1210
|
if arg.is_a?(Symbol)
|
@@ -1227,7 +1230,7 @@ module Steep
|
|
1227
1230
|
|
1228
1231
|
when :mlhs
|
1229
1232
|
yield_self do
|
1230
|
-
constr = self
|
1233
|
+
constr = self #: TypeConstruction
|
1231
1234
|
|
1232
1235
|
node.children.each do |arg|
|
1233
1236
|
_, constr = constr.synthesize(arg)
|
@@ -1353,7 +1356,6 @@ module Steep
|
|
1353
1356
|
ty = node.type == :true ? AST::Types::Literal.new(value: true) : AST::Types::Literal.new(value: false)
|
1354
1357
|
|
1355
1358
|
if hint && check_relation(sub_type: ty, super_type: hint).success? && !hint.is_a?(AST::Types::Any) && !hint.is_a?(AST::Types::Top)
|
1356
|
-
|
1357
1359
|
add_typing(node, type: hint)
|
1358
1360
|
else
|
1359
1361
|
add_typing(node, type: AST::Types::Boolean.new)
|
@@ -1393,8 +1395,11 @@ module Steep
|
|
1393
1395
|
yield_self do
|
1394
1396
|
constr = self
|
1395
1397
|
|
1398
|
+
# @type var name_node: Parser::AST::Node
|
1399
|
+
# @type var super_node: Parser::AST::Node?
|
1400
|
+
|
1396
1401
|
name_node, super_node, _ = node.children
|
1397
|
-
_, constr, class_name =
|
1402
|
+
_, constr, class_name = synthesize_constant_decl(name_node, name_node.children[0], name_node.children[1]) do
|
1398
1403
|
typing.add_error(
|
1399
1404
|
Diagnostic::Ruby::UnknownConstant.new(node: name_node, name: name_node.children[1]).class!
|
1400
1405
|
)
|
@@ -1421,9 +1426,9 @@ module Steep
|
|
1421
1426
|
|
1422
1427
|
with_class_constr(node, class_name, super_name) do |constructor|
|
1423
1428
|
if module_type = constructor.module_context&.module_type
|
1424
|
-
_, constructor = constructor.add_typing(
|
1429
|
+
_, constructor = constructor.add_typing(name_node, type: module_type)
|
1425
1430
|
else
|
1426
|
-
_, constructor = constructor.fallback_to_any(
|
1431
|
+
_, constructor = constructor.fallback_to_any(name_node)
|
1427
1432
|
end
|
1428
1433
|
|
1429
1434
|
constructor.typing.add_context_for_node(node, context: constructor.context)
|
@@ -1443,8 +1448,9 @@ module Steep
|
|
1443
1448
|
yield_self do
|
1444
1449
|
constr = self
|
1445
1450
|
|
1451
|
+
# @type var name_node: Parser::AST::Node
|
1446
1452
|
name_node, _ = node.children
|
1447
|
-
_, constr, module_name =
|
1453
|
+
_, constr, module_name = synthesize_constant_decl(name_node, name_node.children[0], name_node.children[1]) do
|
1448
1454
|
typing.add_error Diagnostic::Ruby::UnknownConstant.new(node: name_node, name: name_node.children[1]).module!
|
1449
1455
|
end
|
1450
1456
|
|
@@ -1454,9 +1460,9 @@ module Steep
|
|
1454
1460
|
|
1455
1461
|
with_module_constr(node, module_name) do |constructor|
|
1456
1462
|
if module_type = constructor.module_context&.module_type
|
1457
|
-
_, constructor = constructor.add_typing(
|
1463
|
+
_, constructor = constructor.add_typing(name_node, type: module_type)
|
1458
1464
|
else
|
1459
|
-
_, constructor = constructor.fallback_to_any(
|
1465
|
+
_, constructor = constructor.fallback_to_any(name_node)
|
1460
1466
|
end
|
1461
1467
|
|
1462
1468
|
constructor.typing.add_context_for_node(node, context: constructor.context)
|
@@ -1492,9 +1498,9 @@ module Steep
|
|
1492
1498
|
|
1493
1499
|
constructor.synthesize(node.children[1]) if node.children[1]
|
1494
1500
|
|
1495
|
-
if constructor.module_context
|
1496
|
-
if constructor.module_context
|
1497
|
-
module_context
|
1501
|
+
if constructor.module_context.instance_definition && module_context.module_definition
|
1502
|
+
if constructor.module_context.instance_definition.type_name == module_context.module_definition.type_name
|
1503
|
+
module_context.defined_module_methods.merge(constructor.module_context.defined_instance_methods)
|
1498
1504
|
end
|
1499
1505
|
end
|
1500
1506
|
end
|
@@ -1521,7 +1527,7 @@ module Steep
|
|
1521
1527
|
|
1522
1528
|
when :casgn
|
1523
1529
|
yield_self do
|
1524
|
-
constant_type, constr, constant_name =
|
1530
|
+
constant_type, constr, constant_name = synthesize_constant_decl(nil, node.children[0], node.children[1]) do
|
1525
1531
|
typing.add_error(
|
1526
1532
|
Diagnostic::Ruby::UnknownConstant.new(
|
1527
1533
|
node: node,
|
@@ -1570,6 +1576,7 @@ module Steep
|
|
1570
1576
|
# @type var errors: Array[Diagnostic::Ruby::Base]
|
1571
1577
|
errors = []
|
1572
1578
|
constr = type_check_args(
|
1579
|
+
nil,
|
1573
1580
|
args,
|
1574
1581
|
Subtyping::Constraints.new(unknowns: []),
|
1575
1582
|
errors
|
@@ -1590,7 +1597,7 @@ module Steep
|
|
1590
1597
|
|
1591
1598
|
when :zsuper
|
1592
1599
|
yield_self do
|
1593
|
-
if method_context
|
1600
|
+
if method_context && method_context.method
|
1594
1601
|
if method_context.super_method
|
1595
1602
|
types = method_context.super_method.method_types.map {|method_type|
|
1596
1603
|
checker.factory.method_type(method_type, method_decls: Set[]).type.return_type
|
@@ -1623,22 +1630,28 @@ module Steep
|
|
1623
1630
|
else
|
1624
1631
|
node_range = node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
|
1625
1632
|
|
1626
|
-
if hint
|
1627
|
-
tuples
|
1628
|
-
|
1629
|
-
|
1630
|
-
|
1633
|
+
if hint
|
1634
|
+
tuples = select_flatten_types(hint) {|type| type.is_a?(AST::Types::Tuple) } #: Array[AST::Types::Tuple]
|
1635
|
+
unless tuples.empty?
|
1636
|
+
tuples.each do |tuple|
|
1637
|
+
typing.new_child(node_range) do |child_typing|
|
1638
|
+
if pair = with_new_typing(child_typing).try_tuple_type(node, tuple)
|
1639
|
+
return pair.with(constr: pair.constr.save_typing)
|
1640
|
+
end
|
1631
1641
|
end
|
1632
1642
|
end
|
1633
1643
|
end
|
1634
1644
|
end
|
1635
1645
|
|
1636
|
-
if hint
|
1637
|
-
arrays
|
1638
|
-
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1646
|
+
if hint
|
1647
|
+
arrays = select_flatten_types(hint) {|type| AST::Builtin::Array.instance_type?(type) } #: Array[AST::Types::Name::Instance]
|
1648
|
+
unless arrays.empty?
|
1649
|
+
arrays.each do |array|
|
1650
|
+
typing.new_child(node_range) do |child_typing|
|
1651
|
+
pair = with_new_typing(child_typing).try_array_type(node, array)
|
1652
|
+
if pair.constr.check_relation(sub_type: pair.type, super_type: hint).success?
|
1653
|
+
return pair.with(constr: pair.constr.save_typing)
|
1654
|
+
end
|
1642
1655
|
end
|
1643
1656
|
end
|
1644
1657
|
end
|
@@ -1771,7 +1784,7 @@ module Steep
|
|
1771
1784
|
end
|
1772
1785
|
|
1773
1786
|
constr = constr.update_type_env do |env|
|
1774
|
-
envs = []
|
1787
|
+
envs = [] #: Array[TypeInference::TypeEnv]
|
1775
1788
|
|
1776
1789
|
if true_pair
|
1777
1790
|
unless true_pair.type.is_a?(AST::Types::Bot)
|
@@ -1798,13 +1811,15 @@ module Steep
|
|
1798
1811
|
|
1799
1812
|
when :case
|
1800
1813
|
yield_self do
|
1814
|
+
# @type var node: Parser::AST::Node & Parser::AST::_CaseNode
|
1815
|
+
|
1801
1816
|
cond, *whens, els = node.children
|
1802
1817
|
|
1803
|
-
constr = self
|
1818
|
+
constr = self #: TypeConstruction
|
1804
1819
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing, config: builder_config)
|
1805
1820
|
|
1806
1821
|
if cond
|
1807
|
-
branch_results = []
|
1822
|
+
branch_results = [] #: Array[Pair]
|
1808
1823
|
|
1809
1824
|
cond_type, constr = constr.synthesize(cond)
|
1810
1825
|
_, cond_vars = interpreter.decompose_value(cond)
|
@@ -1858,6 +1873,8 @@ module Steep
|
|
1858
1873
|
end
|
1859
1874
|
|
1860
1875
|
if els
|
1876
|
+
node.loc.else or raise
|
1877
|
+
|
1861
1878
|
begin_pos = node.loc.else.end_pos
|
1862
1879
|
end_pos = node.loc.end.begin_pos
|
1863
1880
|
typing.add_context(begin_pos..end_pos, context: when_constr.context)
|
@@ -1885,14 +1902,14 @@ module Steep
|
|
1885
1902
|
end
|
1886
1903
|
end
|
1887
1904
|
else
|
1888
|
-
branch_results = []
|
1905
|
+
branch_results = [] #: Array[Pair]
|
1889
1906
|
|
1890
1907
|
condition_constr = constr
|
1891
1908
|
clause_constr = constr
|
1892
1909
|
|
1893
1910
|
whens.each do |when_clause|
|
1894
1911
|
when_clause_constr = condition_constr
|
1895
|
-
body_envs = []
|
1912
|
+
body_envs = [] #: Array[TypeInference::TypeEnv]
|
1896
1913
|
|
1897
1914
|
*tests, body = when_clause.children
|
1898
1915
|
|
@@ -1975,7 +1992,7 @@ module Steep
|
|
1975
1992
|
end
|
1976
1993
|
|
1977
1994
|
resbody_construction = body_constr.for_branch(resbody).update_type_env do |env|
|
1978
|
-
assignments = {}
|
1995
|
+
assignments = {} #: Hash[Symbol, AST::Types::t]
|
1979
1996
|
|
1980
1997
|
case
|
1981
1998
|
when exn_classes && var_name && exn_types
|
@@ -2025,8 +2042,12 @@ module Steep
|
|
2025
2042
|
klasses, asgn, body = node.children
|
2026
2043
|
synthesize(klasses) if klasses
|
2027
2044
|
synthesize(asgn) if asgn
|
2028
|
-
|
2029
|
-
|
2045
|
+
if body
|
2046
|
+
body_type = synthesize(body, hint: hint).type
|
2047
|
+
add_typing(node, type: body_type)
|
2048
|
+
else
|
2049
|
+
add_typing(node, type: AST::Builtin.nil_type)
|
2050
|
+
end
|
2030
2051
|
end
|
2031
2052
|
|
2032
2053
|
when :ensure
|
@@ -2034,7 +2055,11 @@ module Steep
|
|
2034
2055
|
body, ensure_body = node.children
|
2035
2056
|
body_type = synthesize(body).type if body
|
2036
2057
|
synthesize(ensure_body) if ensure_body
|
2037
|
-
|
2058
|
+
if body_type
|
2059
|
+
add_typing(node, type: body_type)
|
2060
|
+
else
|
2061
|
+
add_typing(node, type: AST::Builtin.nil_type)
|
2062
|
+
end
|
2038
2063
|
end
|
2039
2064
|
|
2040
2065
|
when :masgn
|
@@ -2054,13 +2079,13 @@ module Steep
|
|
2054
2079
|
if method_type = (each.method_types || []).find {|type| type.block && type.block.type.params.first_param }
|
2055
2080
|
if block = method_type.block
|
2056
2081
|
if first_param = block.type.params.first_param
|
2057
|
-
var_type = first_param.type
|
2082
|
+
var_type = first_param.type #: AST::Types::t
|
2058
2083
|
end
|
2059
2084
|
end
|
2060
2085
|
end
|
2061
2086
|
end
|
2062
2087
|
end
|
2063
|
-
var_name = asgn.children[0]
|
2088
|
+
var_name = asgn.children[0] #: Symbol
|
2064
2089
|
|
2065
2090
|
if var_type
|
2066
2091
|
if body
|
@@ -2106,8 +2131,14 @@ module Steep
|
|
2106
2131
|
body_env, exit_env = truthy_env, falsy_env
|
2107
2132
|
when :until
|
2108
2133
|
exit_env, body_env = truthy_env, falsy_env
|
2134
|
+
else
|
2135
|
+
raise
|
2109
2136
|
end
|
2110
2137
|
|
2138
|
+
body_env or raise
|
2139
|
+
exit_env or raise
|
2140
|
+
|
2141
|
+
|
2111
2142
|
if body
|
2112
2143
|
pins = body_env.pin_local_variables(nil)
|
2113
2144
|
body_env = body_env.merge(local_variable_types: pins)
|
@@ -2131,7 +2162,7 @@ module Steep
|
|
2131
2162
|
yield_self do
|
2132
2163
|
cond, body = node.children
|
2133
2164
|
|
2134
|
-
_, cond_constr, = synthesize(cond)
|
2165
|
+
_, cond_constr, = synthesize(cond)
|
2135
2166
|
|
2136
2167
|
if body
|
2137
2168
|
for_loop =
|
@@ -2146,7 +2177,7 @@ module Steep
|
|
2146
2177
|
|
2147
2178
|
add_typing(node, type: AST::Builtin.nil_type, constr: constr)
|
2148
2179
|
else
|
2149
|
-
add_typing(node, type: AST::Builtin.nil_type, constr:
|
2180
|
+
add_typing(node, type: AST::Builtin.nil_type, constr: cond_constr)
|
2150
2181
|
end
|
2151
2182
|
end
|
2152
2183
|
|
@@ -2155,12 +2186,12 @@ module Steep
|
|
2155
2186
|
|
2156
2187
|
constr = self
|
2157
2188
|
begin_type, constr = if begin_node
|
2158
|
-
constr.synthesize(begin_node)
|
2189
|
+
constr.synthesize(begin_node).to_ary
|
2159
2190
|
else
|
2160
2191
|
[AST::Builtin.nil_type, constr]
|
2161
2192
|
end
|
2162
2193
|
end_type, constr = if end_node
|
2163
|
-
constr.synthesize(end_node)
|
2194
|
+
constr.synthesize(end_node).to_ary
|
2164
2195
|
else
|
2165
2196
|
[AST::Builtin.nil_type, constr]
|
2166
2197
|
end
|
@@ -2298,14 +2329,18 @@ module Steep
|
|
2298
2329
|
Steep.logger.error "Passing multiple args through Symbol#to_proc is not supported yet"
|
2299
2330
|
end
|
2300
2331
|
when value == nil
|
2301
|
-
|
2302
|
-
type
|
2303
|
-
|
2304
|
-
|
2305
|
-
|
2306
|
-
|
2307
|
-
|
2308
|
-
|
2332
|
+
if block_type = method_context!.block_type
|
2333
|
+
type = AST::Types::Proc.new(
|
2334
|
+
type: block_type.type,
|
2335
|
+
location: nil,
|
2336
|
+
block: nil,
|
2337
|
+
self_type: block_type.self_type
|
2338
|
+
)
|
2339
|
+
if block_type.optional?
|
2340
|
+
type = AST::Types::Union.build(types: [type, AST::Builtin.nil_type])
|
2341
|
+
end
|
2342
|
+
else
|
2343
|
+
type = AST::Builtin.nil_type
|
2309
2344
|
end
|
2310
2345
|
end
|
2311
2346
|
|
@@ -2328,9 +2363,12 @@ module Steep
|
|
2328
2363
|
|
2329
2364
|
type, constr = synthesize(rhs, hint: hint)
|
2330
2365
|
|
2331
|
-
var_type =
|
2332
|
-
|
2333
|
-
|
2366
|
+
var_type =
|
2367
|
+
if class_vars = module_context.class_variables
|
2368
|
+
if ty = class_vars[name]
|
2369
|
+
checker.factory.type(ty)
|
2370
|
+
end
|
2371
|
+
end
|
2334
2372
|
|
2335
2373
|
if var_type
|
2336
2374
|
result = constr.check_relation(sub_type: type, super_type: var_type)
|
@@ -2352,10 +2390,13 @@ module Steep
|
|
2352
2390
|
end
|
2353
2391
|
|
2354
2392
|
when :cvar
|
2355
|
-
name = node.children[0]
|
2356
|
-
var_type =
|
2357
|
-
|
2358
|
-
|
2393
|
+
name = node.children[0] #: Symbol
|
2394
|
+
var_type =
|
2395
|
+
if cvs = module_context.class_variables
|
2396
|
+
if ty = cvs[name]
|
2397
|
+
checker.factory.type(ty)
|
2398
|
+
end
|
2399
|
+
end
|
2359
2400
|
|
2360
2401
|
if var_type
|
2361
2402
|
add_typing node, type: var_type
|
@@ -2383,7 +2424,7 @@ module Steep
|
|
2383
2424
|
end
|
2384
2425
|
|
2385
2426
|
when :args
|
2386
|
-
constr = self
|
2427
|
+
constr = self #: TypeConstruction
|
2387
2428
|
|
2388
2429
|
each_child_node(node) do |child|
|
2389
2430
|
_, constr = constr.synthesize(child)
|
@@ -2396,7 +2437,7 @@ module Steep
|
|
2396
2437
|
# @type var as_type: AST::Node::TypeAssertion
|
2397
2438
|
asserted_node, as_type = node.children
|
2398
2439
|
|
2399
|
-
if type = as_type.type?(module_context
|
2440
|
+
if type = as_type.type?(module_context.nesting, checker.factory, [])
|
2400
2441
|
actual_type, constr = synthesize(asserted_node, hint: type)
|
2401
2442
|
|
2402
2443
|
if no_subtyping?(sub_type: type, super_type: actual_type) && no_subtyping?(sub_type: actual_type, super_type: type)
|
@@ -2426,6 +2467,9 @@ module Steep
|
|
2426
2467
|
constr.add_typing(node, type: type)
|
2427
2468
|
end
|
2428
2469
|
|
2470
|
+
when :forwarded_args, :forward_arg
|
2471
|
+
add_typing(node, type: AST::Builtin.any_type)
|
2472
|
+
|
2429
2473
|
else
|
2430
2474
|
typing.add_error(Diagnostic::Ruby::UnsupportedSyntax.new(node: node))
|
2431
2475
|
add_typing(node, type: AST::Builtin.any_type)
|
@@ -2439,7 +2483,7 @@ module Steep
|
|
2439
2483
|
end
|
2440
2484
|
rescue RBS::BaseError => exn
|
2441
2485
|
Steep.logger.warn { "Unexpected RBS error: #{exn.message}" }
|
2442
|
-
exn.backtrace
|
2486
|
+
exn.backtrace&.each {|loc| Steep.logger.warn " #{loc}" }
|
2443
2487
|
typing.add_error(Diagnostic::Ruby::UnexpectedError.new(node: node, error: exn))
|
2444
2488
|
type_any_rec(node)
|
2445
2489
|
rescue StandardError => exn
|
@@ -2466,7 +2510,7 @@ module Steep
|
|
2466
2510
|
when :send
|
2467
2511
|
yield_self do
|
2468
2512
|
if self_class?(node)
|
2469
|
-
module_type = expand_alias(module_context
|
2513
|
+
module_type = expand_alias(module_context.module_type)
|
2470
2514
|
type = if module_type.is_a?(AST::Types::Name::Singleton)
|
2471
2515
|
AST::Types::Name::Singleton.new(name: module_type.name)
|
2472
2516
|
else
|
@@ -2482,7 +2526,7 @@ module Steep
|
|
2482
2526
|
yield_self do
|
2483
2527
|
send_type, constr =
|
2484
2528
|
if self_class?(node)
|
2485
|
-
module_type = expand_alias(module_context
|
2529
|
+
module_type = expand_alias(module_context.module_type)
|
2486
2530
|
type = if module_type.is_a?(AST::Types::Name::Singleton)
|
2487
2531
|
AST::Types::Name::Singleton.new(name: module_type.name)
|
2488
2532
|
else
|
@@ -2501,6 +2545,7 @@ module Steep
|
|
2501
2545
|
yield_self do
|
2502
2546
|
send_node, params, body = node.children
|
2503
2547
|
if send_node.type == :lambda
|
2548
|
+
# @type var node: Parser::AST::Node & Parser::AST::_BlockNode
|
2504
2549
|
type_lambda(node, params_node: params, body_node: body, type_hint: hint)
|
2505
2550
|
else
|
2506
2551
|
type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend, tapp: tapp)
|
@@ -2519,6 +2564,7 @@ module Steep
|
|
2519
2564
|
params = Parser::AST::Node.new(:args, arg_nodes)
|
2520
2565
|
|
2521
2566
|
if send_node.type == :lambda
|
2567
|
+
# @type var node: Parser::AST::Node & Parser::AST::_BlockNode
|
2522
2568
|
type_lambda(node, params_node: params, body_node: body, type_hint: hint)
|
2523
2569
|
else
|
2524
2570
|
type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend, tapp: tapp)
|
@@ -2632,7 +2678,7 @@ module Steep
|
|
2632
2678
|
hint = masgn.hint_for_mlhs(lhs, context.type_env)
|
2633
2679
|
|
2634
2680
|
rhs_type, lhs_constr = try_tuple_type!(rhs, hint: hint).to_ary
|
2635
|
-
rhs_type = deep_expand_alias(rhs_type)
|
2681
|
+
rhs_type = deep_expand_alias(rhs_type) || rhs_type
|
2636
2682
|
|
2637
2683
|
falsys, truthys = partition_flatten_types(rhs_type) do |type|
|
2638
2684
|
type.is_a?(AST::Types::Nil) || (type.is_a?(AST::Types::Literal) && type.value == false)
|
@@ -2680,6 +2726,57 @@ module Steep
|
|
2680
2726
|
constr.add_typing(node, type: truthy_rhs_type)
|
2681
2727
|
end
|
2682
2728
|
|
2729
|
+
def synthesize_constant_decl(node, parent_node, constant_name, &block)
|
2730
|
+
const_name = module_name_from_node(parent_node, constant_name)
|
2731
|
+
|
2732
|
+
if const_name && type = context.type_env.annotated_constant(const_name)
|
2733
|
+
# const-type annotation wins
|
2734
|
+
if node
|
2735
|
+
constr = synthesize_children(node)
|
2736
|
+
type, constr = constr.add_typing(node, type: type)
|
2737
|
+
[type, constr, nil]
|
2738
|
+
else
|
2739
|
+
[type, self, nil]
|
2740
|
+
end
|
2741
|
+
else
|
2742
|
+
if parent_node
|
2743
|
+
synthesize_constant(node, parent_node, constant_name, &block)
|
2744
|
+
else
|
2745
|
+
if nesting
|
2746
|
+
if parent_nesting = nesting[1]
|
2747
|
+
if constant = context.type_env.constant_env.resolver.table.children(parent_nesting)&.fetch(constant_name, nil)
|
2748
|
+
return [checker.factory.type(constant.type), self, constant.name]
|
2749
|
+
end
|
2750
|
+
end
|
2751
|
+
|
2752
|
+
if block_given?
|
2753
|
+
yield
|
2754
|
+
else
|
2755
|
+
if node
|
2756
|
+
typing.add_error(
|
2757
|
+
Diagnostic::Ruby::UnknownConstant.new(node: node, name: constant_name)
|
2758
|
+
)
|
2759
|
+
end
|
2760
|
+
end
|
2761
|
+
|
2762
|
+
constr = self #: TypeConstruction
|
2763
|
+
if node
|
2764
|
+
_, constr = add_typing(node, type: AST::Builtin.any_type)
|
2765
|
+
end
|
2766
|
+
|
2767
|
+
[
|
2768
|
+
AST::Builtin.any_type,
|
2769
|
+
constr,
|
2770
|
+
nil
|
2771
|
+
]
|
2772
|
+
else
|
2773
|
+
# No neesting
|
2774
|
+
synthesize_constant(node, nil, constant_name, &block)
|
2775
|
+
end
|
2776
|
+
end
|
2777
|
+
end
|
2778
|
+
end
|
2779
|
+
|
2683
2780
|
def synthesize_constant(node, parent_node, constant_name)
|
2684
2781
|
const_name = module_name_from_node(parent_node, constant_name)
|
2685
2782
|
|
@@ -2795,7 +2892,7 @@ module Steep
|
|
2795
2892
|
|
2796
2893
|
block_constr.typing.add_context_for_body(node, context: block_constr.context)
|
2797
2894
|
|
2798
|
-
params.
|
2895
|
+
params.each_single_param do |param|
|
2799
2896
|
_, block_constr = block_constr.synthesize(param.node, hint: param.type)
|
2800
2897
|
end
|
2801
2898
|
|
@@ -2843,8 +2940,13 @@ module Steep
|
|
2843
2940
|
Interface::Substitution.build([], [], self_type: block_constr.self_type)
|
2844
2941
|
)
|
2845
2942
|
|
2846
|
-
if expected_block_type = block_constr.block_context
|
2847
|
-
type_vars = expected_block_type.free_variables
|
2943
|
+
if expected_block_type = block_constr.block_context!.body_type
|
2944
|
+
type_vars = expected_block_type.free_variables.filter_map do |var|
|
2945
|
+
case var
|
2946
|
+
when Symbol
|
2947
|
+
var
|
2948
|
+
end
|
2949
|
+
end
|
2848
2950
|
subst = Interface::Substitution.build(type_vars, type_vars.map { AST::Builtin.any_type })
|
2849
2951
|
expected_block_type = expected_block_type.subst(subst)
|
2850
2952
|
|
@@ -2879,7 +2981,7 @@ module Steep
|
|
2879
2981
|
end
|
2880
2982
|
|
2881
2983
|
def synthesize_children(node, skips: [])
|
2882
|
-
skips = Set.new.compare_by_identity.merge(skips)
|
2984
|
+
skips = Set.new.compare_by_identity.merge(skips).delete(nil)
|
2883
2985
|
|
2884
2986
|
# @type var constr: TypeConstruction
|
2885
2987
|
constr = self
|
@@ -2902,8 +3004,11 @@ module Steep
|
|
2902
3004
|
return false unless call.node.type == :send || call.node.type == :csend
|
2903
3005
|
return false unless call.pure? || KNOWN_PURE_METHODS.superset?(Set.new(call.method_decls.map(&:method_name)))
|
2904
3006
|
|
2905
|
-
[
|
2906
|
-
|
3007
|
+
argishes = [*arguments]
|
3008
|
+
argishes << receiver if receiver
|
3009
|
+
|
3010
|
+
argishes.all? do |node|
|
3011
|
+
value_node?(node) || context.type_env[node]
|
2907
3012
|
end
|
2908
3013
|
end
|
2909
3014
|
|
@@ -2944,7 +3049,11 @@ module Steep
|
|
2944
3049
|
end
|
2945
3050
|
else
|
2946
3051
|
constr = constr.update_type_env do |env|
|
2947
|
-
|
3052
|
+
if receiver
|
3053
|
+
env.invalidate_pure_node(receiver)
|
3054
|
+
else
|
3055
|
+
env
|
3056
|
+
end
|
2948
3057
|
end
|
2949
3058
|
end
|
2950
3059
|
end
|
@@ -2955,13 +3064,14 @@ module Steep
|
|
2955
3064
|
call = call.with_return_type(optional_type)
|
2956
3065
|
end
|
2957
3066
|
else
|
2958
|
-
errors = []
|
3067
|
+
errors = [] #: Array[Diagnostic::Ruby::Base]
|
2959
3068
|
|
2960
3069
|
skips = [receiver]
|
2961
3070
|
skips << node.children[0] if node.type == :block
|
2962
3071
|
|
2963
3072
|
constr = synthesize_children(node, skips: skips)
|
2964
3073
|
if block_params
|
3074
|
+
# @type var node: Parser::AST::Node & Parser::AST::_BlockNode
|
2965
3075
|
block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
|
2966
3076
|
|
2967
3077
|
constr.type_block_without_hint(
|
@@ -2982,7 +3092,7 @@ module Steep
|
|
2982
3092
|
)
|
2983
3093
|
call = TypeInference::MethodCall::Error.new(
|
2984
3094
|
node: node,
|
2985
|
-
context: context.
|
3095
|
+
context: context.call_context,
|
2986
3096
|
method_name: method_name,
|
2987
3097
|
receiver_type: receiver_type,
|
2988
3098
|
errors: errors
|
@@ -2991,7 +3101,7 @@ module Steep
|
|
2991
3101
|
|
2992
3102
|
constr.add_call(call)
|
2993
3103
|
else
|
2994
|
-
skips = []
|
3104
|
+
skips = [] #: Array[Parser::AST::Node?]
|
2995
3105
|
skips << receiver if receiver
|
2996
3106
|
skips << node.children[0] if node.type == :block
|
2997
3107
|
skips << block_params if block_params
|
@@ -2999,6 +3109,7 @@ module Steep
|
|
2999
3109
|
|
3000
3110
|
constr = synthesize_children(node, skips: skips)
|
3001
3111
|
if block_params
|
3112
|
+
# @type var node: Parser::AST::Node & Parser::AST::_BlockNode
|
3002
3113
|
block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
|
3003
3114
|
|
3004
3115
|
constr.type_block_without_hint(
|
@@ -3023,7 +3134,7 @@ module Steep
|
|
3023
3134
|
constr.add_call(
|
3024
3135
|
TypeInference::MethodCall::NoMethodError.new(
|
3025
3136
|
node: node,
|
3026
|
-
context: context.
|
3137
|
+
context: context.call_context,
|
3027
3138
|
method_name: method_name,
|
3028
3139
|
receiver_type: receiver_type,
|
3029
3140
|
error: Diagnostic::Ruby::NoMethod.new(node: node, method: method_name, type: interface&.type || receiver_type)
|
@@ -3079,7 +3190,7 @@ module Steep
|
|
3079
3190
|
constr.add_call(
|
3080
3191
|
TypeInference::MethodCall::Untyped.new(
|
3081
3192
|
node: node,
|
3082
|
-
context: context.
|
3193
|
+
context: context.call_context,
|
3083
3194
|
method_name: method_name
|
3084
3195
|
)
|
3085
3196
|
)
|
@@ -3091,7 +3202,7 @@ module Steep
|
|
3091
3202
|
interface: interface,
|
3092
3203
|
receiver: receiver,
|
3093
3204
|
receiver_type: receiver_type,
|
3094
|
-
|
3205
|
+
method_name: method_name,
|
3095
3206
|
arguments: arguments,
|
3096
3207
|
block_params: block_params,
|
3097
3208
|
block_body: block_body,
|
@@ -3102,7 +3213,7 @@ module Steep
|
|
3102
3213
|
constr.add_call(
|
3103
3214
|
TypeInference::MethodCall::NoMethodError.new(
|
3104
3215
|
node: node,
|
3105
|
-
context: context.
|
3216
|
+
context: context.call_context,
|
3106
3217
|
method_name: method_name,
|
3107
3218
|
receiver_type: receiver_type,
|
3108
3219
|
error: Diagnostic::Ruby::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
@@ -3117,8 +3228,8 @@ module Steep
|
|
3117
3228
|
def builder_config
|
3118
3229
|
Interface::Builder::Config.new(
|
3119
3230
|
self_type: self_type,
|
3120
|
-
class_type: module_context
|
3121
|
-
instance_type: module_context
|
3231
|
+
class_type: module_context.module_type,
|
3232
|
+
instance_type: module_context.instance_type,
|
3122
3233
|
variable_bounds: variable_context.upper_bounds
|
3123
3234
|
)
|
3124
3235
|
end
|
@@ -3173,7 +3284,7 @@ module Steep
|
|
3173
3284
|
_, constr = add_typing(node, type: type)
|
3174
3285
|
call = TypeInference::MethodCall::Special.new(
|
3175
3286
|
node: node,
|
3176
|
-
context: constr.context.
|
3287
|
+
context: constr.context.call_context,
|
3177
3288
|
method_name: decl.method_name.method_name,
|
3178
3289
|
receiver_type: receiver_type,
|
3179
3290
|
actual_method_type: method_type.with(type: method_type.type.with(return_type: type)),
|
@@ -3197,7 +3308,7 @@ module Steep
|
|
3197
3308
|
_, constr = add_typing(node, type: type)
|
3198
3309
|
call = TypeInference::MethodCall::Special.new(
|
3199
3310
|
node: node,
|
3200
|
-
context: constr.context.
|
3311
|
+
context: constr.context.call_context,
|
3201
3312
|
method_name: decl.method_name.method_name,
|
3202
3313
|
receiver_type: receiver_type,
|
3203
3314
|
actual_method_type: method_type.with(type: method_type.type.with(return_type: type)),
|
@@ -3214,7 +3325,7 @@ module Steep
|
|
3214
3325
|
end
|
3215
3326
|
|
3216
3327
|
def type_method_call(node, method_name:, receiver_type:, method:, arguments:, block_params:, block_body:, tapp:)
|
3217
|
-
node_range = node.loc.expression.
|
3328
|
+
node_range = node.loc.expression.to_range
|
3218
3329
|
|
3219
3330
|
# @type var fails: Array[[TypeInference::MethodCall::t, TypeConstruction]]
|
3220
3331
|
fails = []
|
@@ -3327,11 +3438,11 @@ module Steep
|
|
3327
3438
|
end
|
3328
3439
|
end
|
3329
3440
|
|
3330
|
-
def type_check_args(args, constraints, errors)
|
3441
|
+
def type_check_args(method_name, args, constraints, errors)
|
3331
3442
|
# @type var constr: TypeConstruction
|
3332
3443
|
constr = self
|
3333
3444
|
|
3334
|
-
es = args.each do |arg|
|
3445
|
+
forwarded_args, es = args.each do |arg|
|
3335
3446
|
case arg
|
3336
3447
|
when TypeInference::SendArgs::PositionalArgs::NodeParamPair
|
3337
3448
|
_, constr = constr.type_check_argument(
|
@@ -3404,20 +3515,48 @@ module Steep
|
|
3404
3515
|
|
3405
3516
|
when TypeInference::SendArgs::KeywordArgs::MissingKeyword
|
3406
3517
|
# ignore
|
3518
|
+
|
3407
3519
|
else
|
3408
|
-
raise arg.inspect
|
3520
|
+
raise (_ = arg).inspect
|
3409
3521
|
end
|
3410
3522
|
end
|
3411
3523
|
|
3412
3524
|
errors.push(*es)
|
3413
3525
|
|
3526
|
+
if forwarded_args
|
3527
|
+
method_name or raise "method_name cannot be nil if `forwarded_args` is given, because proc/block doesn't support `...` arg"
|
3528
|
+
|
3529
|
+
(params, block = context.method_context&.forward_arg_type) or raise
|
3530
|
+
|
3531
|
+
checker.with_context(self_type: self_type, instance_type: context.module_context.instance_type, class_type: context.module_context.module_type, constraints: constraints) do
|
3532
|
+
result = checker.check_method_params(
|
3533
|
+
:"... (argument forwarding)",
|
3534
|
+
Subtyping::Relation.new(
|
3535
|
+
sub_type: forwarded_args.params,
|
3536
|
+
super_type: params
|
3537
|
+
)
|
3538
|
+
)
|
3539
|
+
|
3540
|
+
if result.failure?
|
3541
|
+
errors.push(
|
3542
|
+
Diagnostic::Ruby::IncompatibleArgumentForwarding.new(
|
3543
|
+
method_name: method_name,
|
3544
|
+
node: forwarded_args.node,
|
3545
|
+
params_pair: [params, forwarded_args.params],
|
3546
|
+
result: result
|
3547
|
+
)
|
3548
|
+
)
|
3549
|
+
end
|
3550
|
+
end
|
3551
|
+
end
|
3552
|
+
|
3414
3553
|
constr
|
3415
3554
|
end
|
3416
3555
|
|
3417
3556
|
def try_method_type(node, receiver_type:, method_name:, method_type:, arguments:, block_params:, block_body:, tapp:)
|
3418
3557
|
constr = self
|
3419
3558
|
|
3420
|
-
if tapp && type_args = tapp.types?(module_context
|
3559
|
+
if tapp && type_args = tapp.types?(module_context.nesting, checker.factory, [])
|
3421
3560
|
type_arity = method_type.type_params.size
|
3422
3561
|
type_param_names = method_type.type_params.map(&:name)
|
3423
3562
|
|
@@ -3477,7 +3616,7 @@ module Steep
|
|
3477
3616
|
)
|
3478
3617
|
end
|
3479
3618
|
|
3480
|
-
type_params = []
|
3619
|
+
type_params = [] #: Array[Interface::TypeParam]
|
3481
3620
|
type_param_names.clear
|
3482
3621
|
else
|
3483
3622
|
# Infer type application
|
@@ -3499,12 +3638,12 @@ module Steep
|
|
3499
3638
|
constraints = Subtyping::Constraints.new(unknowns: type_params.map(&:name))
|
3500
3639
|
ccontext = Subtyping::Constraints::Context.new(
|
3501
3640
|
self_type: self_type,
|
3502
|
-
instance_type: module_context
|
3503
|
-
class_type: module_context
|
3641
|
+
instance_type: module_context.instance_type,
|
3642
|
+
class_type: module_context.module_type,
|
3504
3643
|
variance: variance
|
3505
3644
|
)
|
3506
3645
|
|
3507
|
-
upper_bounds = {}
|
3646
|
+
upper_bounds = {} #: Hash[Symbol, AST::Types::t]
|
3508
3647
|
|
3509
3648
|
type_params.each do |param|
|
3510
3649
|
if ub = param.upper_bound
|
@@ -3514,11 +3653,14 @@ module Steep
|
|
3514
3653
|
end
|
3515
3654
|
|
3516
3655
|
checker.push_variable_bounds(upper_bounds) do
|
3656
|
+
# @type block: [TypeInference::MethodCall::t, TypeConstruction]
|
3657
|
+
|
3517
3658
|
# @type var errors: Array[Diagnostic::Ruby::Base]
|
3518
3659
|
errors = []
|
3519
3660
|
|
3520
3661
|
args = TypeInference::SendArgs.new(node: node, arguments: arguments, type: method_type)
|
3521
3662
|
constr = constr.type_check_args(
|
3663
|
+
method_name,
|
3522
3664
|
args,
|
3523
3665
|
constraints,
|
3524
3666
|
errors
|
@@ -3526,6 +3668,8 @@ module Steep
|
|
3526
3668
|
|
3527
3669
|
if block_params
|
3528
3670
|
# block is given
|
3671
|
+
# @type var node: Parser::AST::Node & Parser::AST::_BlockNode
|
3672
|
+
|
3529
3673
|
block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
|
3530
3674
|
block_params_ = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
|
3531
3675
|
|
@@ -3596,12 +3740,14 @@ module Steep
|
|
3596
3740
|
)
|
3597
3741
|
}
|
3598
3742
|
|
3743
|
+
method_type.block or raise
|
3744
|
+
|
3599
3745
|
if solved
|
3600
3746
|
# Ready for type check the body of the block
|
3601
3747
|
block_constr = block_constr.update_type_env {|env| env.subst(s) }
|
3602
3748
|
block_constr = block_constr.update_context {|context|
|
3603
3749
|
context.with(
|
3604
|
-
self_type: method_type.block
|
3750
|
+
self_type: method_type.block.self_type || context.self_type,
|
3605
3751
|
type_env: context.type_env.subst(s),
|
3606
3752
|
block_context: context.block_context&.subst(s),
|
3607
3753
|
break_context: context.break_context&.subst(s)
|
@@ -3708,6 +3854,21 @@ module Steep
|
|
3708
3854
|
arg = args.block_pass_arg
|
3709
3855
|
|
3710
3856
|
case
|
3857
|
+
when forwarded_args_node = args.forwarded_args_node
|
3858
|
+
(_, block = method_context!.forward_arg_type) or raise
|
3859
|
+
|
3860
|
+
method_block_type = method_type.block&.to_proc_type || AST::Builtin.nil_type
|
3861
|
+
forwarded_block_type = block&.to_proc_type || AST::Builtin.nil_type
|
3862
|
+
|
3863
|
+
if result = constr.no_subtyping?(sub_type: forwarded_block_type, super_type: method_block_type)
|
3864
|
+
errors << Diagnostic::Ruby::IncompatibleArgumentForwarding.new(
|
3865
|
+
method_name: method_name,
|
3866
|
+
node: forwarded_args_node,
|
3867
|
+
block_pair: [block, method_type.block],
|
3868
|
+
result: result
|
3869
|
+
)
|
3870
|
+
end
|
3871
|
+
|
3711
3872
|
when arg.compatible?
|
3712
3873
|
if arg.node
|
3713
3874
|
# Block pass (&block) is given
|
@@ -3770,7 +3931,10 @@ module Steep
|
|
3770
3931
|
)
|
3771
3932
|
|
3772
3933
|
when arg.unexpected_block?
|
3773
|
-
# Unexpected block is given
|
3934
|
+
# Unexpected block pass node is given
|
3935
|
+
|
3936
|
+
arg.node or raise
|
3937
|
+
|
3774
3938
|
method_type, solved, _ = apply_solution(errors, node: node, method_type: method_type) {
|
3775
3939
|
constraints.solution(checker, variables: method_type.free_variables, context: ccontext)
|
3776
3940
|
}
|
@@ -3791,7 +3955,7 @@ module Steep
|
|
3791
3955
|
call = if errors.empty?
|
3792
3956
|
TypeInference::MethodCall::Typed.new(
|
3793
3957
|
node: node,
|
3794
|
-
context: context.
|
3958
|
+
context: context.call_context,
|
3795
3959
|
receiver_type: receiver_type,
|
3796
3960
|
method_name: method_name,
|
3797
3961
|
actual_method_type: method_type,
|
@@ -3801,7 +3965,7 @@ module Steep
|
|
3801
3965
|
else
|
3802
3966
|
TypeInference::MethodCall::Error.new(
|
3803
3967
|
node: node,
|
3804
|
-
context: context.
|
3968
|
+
context: context.call_context,
|
3805
3969
|
receiver_type: receiver_type,
|
3806
3970
|
method_name: method_name,
|
3807
3971
|
return_type: return_type || method_type.type.return_type,
|
@@ -3871,7 +4035,7 @@ module Steep
|
|
3871
4035
|
|
3872
4036
|
block_type = block_constr.synthesize_block(node: node, block_type_hint: nil, block_body: block_body)
|
3873
4037
|
|
3874
|
-
if expected_block_type = block_constr.block_context
|
4038
|
+
if expected_block_type = block_constr.block_context!.body_type
|
3875
4039
|
block_constr.check_relation(sub_type: block_type, super_type: expected_block_type).else do |result|
|
3876
4040
|
Diagnostic::Ruby::BlockBodyTypeMismatch.new(
|
3877
4041
|
node: node,
|
@@ -3947,8 +4111,7 @@ module Steep
|
|
3947
4111
|
|
3948
4112
|
param_types_hash.delete_if {|name, _| SPECIAL_LVAR_NAMES.include?(name) }
|
3949
4113
|
|
3950
|
-
param_types = param_types_hash.each.with_object({}) do |pair, hash|
|
3951
|
-
# @type var hash: Hash[Symbol, [AST::Types::t, AST::Types::t?]]
|
4114
|
+
param_types = param_types_hash.each.with_object({}) do |pair, hash| #$ Hash[Symbol, [AST::Types::t, AST::Types::t?]]
|
3952
4115
|
name, type = pair
|
3953
4116
|
hash[name] = [type, nil]
|
3954
4117
|
end
|
@@ -4034,7 +4197,7 @@ module Steep
|
|
4034
4197
|
|
4035
4198
|
def synthesize_block(node:, block_type_hint:, block_body:)
|
4036
4199
|
if block_body
|
4037
|
-
body_type, _, context = synthesize(block_body, hint: block_context
|
4200
|
+
body_type, _, context = synthesize(block_body, hint: block_context&.body_type || block_type_hint)
|
4038
4201
|
|
4039
4202
|
range = block_body.loc.expression.end_pos..node.loc.end.begin_pos
|
4040
4203
|
typing.add_context(range, context: context)
|
@@ -4055,7 +4218,7 @@ module Steep
|
|
4055
4218
|
|
4056
4219
|
def union_type(*types)
|
4057
4220
|
raise if types.empty?
|
4058
|
-
AST::Types::Union.build(types: types)
|
4221
|
+
AST::Types::Union.build(types: types.compact)
|
4059
4222
|
end
|
4060
4223
|
|
4061
4224
|
def union_type_unify(*types)
|
@@ -4104,14 +4267,18 @@ module Steep
|
|
4104
4267
|
return unless member_decl_count == 1
|
4105
4268
|
|
4106
4269
|
expected_instance_method_names = (module_context.instance_definition&.methods || {}).each.with_object(Set[]) do |(name, method), set|
|
4107
|
-
if method.implemented_in
|
4108
|
-
|
4270
|
+
if method.implemented_in
|
4271
|
+
if method.implemented_in == module_context.instance_definition&.type_name
|
4272
|
+
set << name
|
4273
|
+
end
|
4109
4274
|
end
|
4110
4275
|
end
|
4111
4276
|
expected_module_method_names = (module_context.module_definition&.methods || {}).each.with_object(Set[]) do |(name, method), set|
|
4112
4277
|
if name != :new
|
4113
|
-
if method.implemented_in
|
4114
|
-
|
4278
|
+
if method.implemented_in
|
4279
|
+
if method.implemented_in == module_context.module_definition&.type_name
|
4280
|
+
set << name
|
4281
|
+
end
|
4115
4282
|
end
|
4116
4283
|
end
|
4117
4284
|
end
|
@@ -4188,18 +4355,20 @@ module Steep
|
|
4188
4355
|
end
|
4189
4356
|
|
4190
4357
|
def namespace_module?(node)
|
4191
|
-
|
4192
|
-
|
4193
|
-
|
4194
|
-
|
4195
|
-
|
4196
|
-
|
4197
|
-
|
4198
|
-
|
4199
|
-
|
4200
|
-
|
4201
|
-
|
4202
|
-
|
4358
|
+
# @type var nodes: Array[Parser::AST::Node]
|
4359
|
+
nodes =
|
4360
|
+
case node.type
|
4361
|
+
when :class, :module
|
4362
|
+
node.children.last&.yield_self {|child|
|
4363
|
+
if child.type == :begin
|
4364
|
+
child.children
|
4365
|
+
else
|
4366
|
+
[child]
|
4367
|
+
end
|
4368
|
+
} || []
|
4369
|
+
else
|
4370
|
+
return false
|
4371
|
+
end
|
4203
4372
|
|
4204
4373
|
!nodes.empty? && nodes.all? {|child| child.type == :class || child.type == :module}
|
4205
4374
|
end
|
@@ -4228,18 +4397,19 @@ module Steep
|
|
4228
4397
|
end
|
4229
4398
|
|
4230
4399
|
def select_flatten_types(type, &block)
|
4231
|
-
types = flatten_union(deep_expand_alias(type))
|
4400
|
+
types = flatten_union(deep_expand_alias(type) || type)
|
4232
4401
|
types.select(&block)
|
4233
4402
|
end
|
4234
4403
|
|
4235
4404
|
def partition_flatten_types(type, &block)
|
4236
|
-
types = flatten_union(deep_expand_alias(type))
|
4405
|
+
types = flatten_union(deep_expand_alias(type) || type)
|
4237
4406
|
types.partition(&block)
|
4238
4407
|
end
|
4239
4408
|
|
4240
4409
|
def flatten_array_elements(type)
|
4241
|
-
flatten_union(deep_expand_alias(type)).flat_map do |type|
|
4410
|
+
flatten_union(deep_expand_alias(type) || type).flat_map do |type|
|
4242
4411
|
if AST::Builtin::Array.instance_type?(type)
|
4412
|
+
# @type var type: AST::Types::Name::Instance
|
4243
4413
|
type.args
|
4244
4414
|
else
|
4245
4415
|
[type]
|
@@ -4248,7 +4418,12 @@ module Steep
|
|
4248
4418
|
end
|
4249
4419
|
|
4250
4420
|
def expand_alias(type, &block)
|
4251
|
-
checker.factory.expand_alias(type
|
4421
|
+
typ = checker.factory.expand_alias(type)
|
4422
|
+
if block
|
4423
|
+
yield(typ)
|
4424
|
+
else
|
4425
|
+
typ
|
4426
|
+
end
|
4252
4427
|
end
|
4253
4428
|
|
4254
4429
|
def test_literal_type(literal, hint)
|
@@ -4296,9 +4471,8 @@ module Steep
|
|
4296
4471
|
def try_tuple_type(array_node, hint)
|
4297
4472
|
raise unless array_node.type == :array
|
4298
4473
|
|
4299
|
-
constr = self
|
4300
|
-
|
4301
|
-
element_types = []
|
4474
|
+
constr = self #: TypeConstruction
|
4475
|
+
element_types = [] #: Array[AST::Types::t]
|
4302
4476
|
|
4303
4477
|
array_node.children.each_with_index do |child, index|
|
4304
4478
|
return if child.type == :splat
|
@@ -4380,11 +4554,14 @@ module Steep
|
|
4380
4554
|
instance_type: module_context.instance_type,
|
4381
4555
|
class_type: module_context.module_type
|
4382
4556
|
)
|
4383
|
-
|
4384
|
-
|
4385
|
-
|
4386
|
-
|
4387
|
-
|
4557
|
+
|
4558
|
+
variables = (type.free_variables + [var.name]).filter_map do |name|
|
4559
|
+
case name
|
4560
|
+
when Symbol
|
4561
|
+
name
|
4562
|
+
end
|
4563
|
+
end
|
4564
|
+
subst = constraints.solution(checker, variables: variables, context: context)
|
4388
4565
|
|
4389
4566
|
type.subst(subst)
|
4390
4567
|
end
|
@@ -4393,8 +4570,8 @@ module Steep
|
|
4393
4570
|
def try_array_type(node, hint)
|
4394
4571
|
element_hint = hint ? hint.args[0] : nil
|
4395
4572
|
|
4396
|
-
constr = self
|
4397
|
-
element_types = []
|
4573
|
+
constr = self #: TypeConstruction
|
4574
|
+
element_types = [] #: Array[AST::Types::t]
|
4398
4575
|
|
4399
4576
|
each_child_node(node) do |child|
|
4400
4577
|
case child.type
|
@@ -4425,24 +4602,24 @@ module Steep
|
|
4425
4602
|
def type_hash_record(hash_node, record_type)
|
4426
4603
|
raise unless hash_node.type == :hash || hash_node.type == :kwargs
|
4427
4604
|
|
4428
|
-
constr = self
|
4605
|
+
constr = self #: TypeConstruction
|
4429
4606
|
|
4430
4607
|
if record_type
|
4431
4608
|
hints = record_type.elements.dup
|
4432
4609
|
else
|
4433
|
-
hints = {}
|
4610
|
+
hints = {} #: Hash[AST::Types::Record::key, AST::Types::t]
|
4434
4611
|
end
|
4435
4612
|
|
4436
|
-
elems = {}
|
4613
|
+
elems = {} #: Hash[AST::Types::Record::key, AST::Types::t]
|
4437
4614
|
|
4438
4615
|
each_child_node(hash_node) do |child|
|
4439
4616
|
if child.type == :pair
|
4440
4617
|
case child.children[0].type
|
4441
4618
|
when :sym, :str, :int
|
4442
|
-
key_node = child.children[0]
|
4443
|
-
value_node = child.children[1]
|
4619
|
+
key_node = child.children[0] #: Parser::AST::Node
|
4620
|
+
value_node = child.children[1] #: Parser::AST::Node
|
4444
4621
|
|
4445
|
-
key = key_node.children[0]
|
4622
|
+
key = key_node.children[0] #: String | Symbol | Integer
|
4446
4623
|
|
4447
4624
|
_, constr = constr.synthesize(key_node, hint: AST::Types::Literal.new(value: key))
|
4448
4625
|
|
@@ -4471,14 +4648,10 @@ module Steep
|
|
4471
4648
|
constr.add_typing(hash_node, type: type)
|
4472
4649
|
end
|
4473
4650
|
|
4474
|
-
# Give hash_node a type based on hint.
|
4475
|
-
#
|
4476
|
-
# * When hint is Record type, it may have record type.
|
4477
|
-
# * When hint is union type, it tries recursively with the union cases.
|
4478
|
-
# * Otherwise, it tries to be a hash instance.
|
4479
|
-
#
|
4480
4651
|
def type_hash(hash_node, hint:)
|
4481
|
-
|
4652
|
+
if hint
|
4653
|
+
hint = deep_expand_alias(hint)
|
4654
|
+
end
|
4482
4655
|
range = hash_node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
|
4483
4656
|
|
4484
4657
|
case hint
|
@@ -4499,10 +4672,11 @@ module Steep
|
|
4499
4672
|
end
|
4500
4673
|
end
|
4501
4674
|
|
4502
|
-
key_types = []
|
4503
|
-
value_types = []
|
4675
|
+
key_types = [] #: Array[AST::Types::t]
|
4676
|
+
value_types = [] #: Array[AST::Types::t]
|
4504
4677
|
|
4505
|
-
if AST::Builtin::Hash.instance_type?(hint)
|
4678
|
+
if hint && AST::Builtin::Hash.instance_type?(hint)
|
4679
|
+
# @type var hint: AST::Types::Name::Instance
|
4506
4680
|
key_hint, value_hint = hint.args
|
4507
4681
|
end
|
4508
4682
|
|
@@ -4511,7 +4685,7 @@ module Steep
|
|
4511
4685
|
value_hint || AST::Builtin.any_type
|
4512
4686
|
)
|
4513
4687
|
|
4514
|
-
constr = self
|
4688
|
+
constr = self #: TypeConstruction
|
4515
4689
|
|
4516
4690
|
if hash_node.children.empty?
|
4517
4691
|
key_types << key_hint if key_hint
|
@@ -4528,14 +4702,13 @@ module Steep
|
|
4528
4702
|
value_types << value_type
|
4529
4703
|
when :kwsplat
|
4530
4704
|
bypass_splat(elem) do |elem_|
|
4531
|
-
|
4532
|
-
|
4533
|
-
|
4534
|
-
|
4535
|
-
|
4705
|
+
constr.synthesize(elem_, hint: hint_hash).tap do |(type, _)|
|
4706
|
+
if AST::Builtin::Hash.instance_type?(type)
|
4707
|
+
# @type var type: AST::Types::Name::Instance
|
4708
|
+
key_types << type.args[0]
|
4709
|
+
value_types << type.args[1]
|
4710
|
+
end
|
4536
4711
|
end
|
4537
|
-
|
4538
|
-
pair
|
4539
4712
|
end
|
4540
4713
|
else
|
4541
4714
|
raise
|
@@ -4573,7 +4746,7 @@ module Steep
|
|
4573
4746
|
|
4574
4747
|
def save_typing
|
4575
4748
|
typing.save!
|
4576
|
-
with_new_typing(typing.parent)
|
4749
|
+
with_new_typing(typing.parent || raise)
|
4577
4750
|
end
|
4578
4751
|
|
4579
4752
|
def extract_outermost_call(node, var_name)
|