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