steep 1.4.0.dev.2 → 1.4.0.dev.4
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 +9 -11
- data/Gemfile.steep +1 -2
- data/Gemfile.steep.lock +11 -14
- 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 +80 -6
- data/lib/steep/drivers/check.rb +4 -4
- data/lib/steep/interface/block.rb +10 -0
- data/lib/steep/interface/builder.rb +3 -3
- data/lib/steep/method_name.rb +8 -0
- data/lib/steep/module_helper.rb +13 -11
- data/lib/steep/path_helper.rb +4 -0
- data/lib/steep/server/interaction_worker.rb +197 -230
- data/lib/steep/server/lsp_formatter.rb +308 -154
- data/lib/steep/server/master.rb +4 -1
- data/lib/steep/services/completion_provider.rb +140 -103
- data/lib/steep/services/hover_provider/rbs.rb +37 -32
- data/lib/steep/services/signature_help_provider.rb +108 -0
- data/lib/steep/services/type_name_completion.rb +165 -0
- data/lib/steep/source.rb +1 -0
- data/lib/steep/type_construction.rb +460 -266
- 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_call.rb +1 -1
- data/lib/steep/type_inference/method_params.rb +42 -16
- data/lib/steep/type_inference/send_args.rb +80 -51
- data/lib/steep/type_inference/type_env.rb +12 -4
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +2 -0
- data/rbs_collection.steep.lock.yaml +0 -28
- data/rbs_collection.steep.yaml +10 -9
- data/sample/Steepfile +2 -0
- data/sample/lib/conference.rb +12 -0
- data/sample/sig/conference.rbs +5 -0
- data/sig/shims/language-server_protocol.rbs +277 -0
- data/sig/shims/parser/nodes.rbs +37 -0
- data/sig/shims/parser.rbs +4 -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/method_name.rbs +5 -1
- 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 +52 -17
- data/sig/steep/server/lsp_formatter.rbs +43 -18
- 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 +106 -28
- data/sig/steep/services/hover_provider/rbs.rbs +13 -9
- data/sig/steep/services/signature_help_provider.rbs +39 -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_call.rbs +1 -1
- 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 +19 -5
- data/sig/steep/typing.rbs +8 -3
- data/smoke/diagnostics/test_expectations.yml +1 -0
- data/steep.gemspec +0 -1
- metadata +12 -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,19 +1902,21 @@ 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
|
|
1914
|
+
# @type var tests: Array[Parser::AST::Node]
|
1915
|
+
# @type var body: Parser::AST::Node?
|
1897
1916
|
*tests, body = when_clause.children
|
1898
1917
|
|
1899
1918
|
tests.each do |test|
|
1900
|
-
test_type, condition_constr = condition_constr.synthesize(test, condition: true)
|
1919
|
+
test_type, condition_constr = condition_constr.synthesize(test, condition: true)
|
1901
1920
|
truthy_env, falsy_env = interpreter.eval(env: condition_constr.context.type_env, node: test)
|
1902
1921
|
|
1903
1922
|
condition_constr = condition_constr.update_type_env { falsy_env }
|
@@ -1975,7 +1994,7 @@ module Steep
|
|
1975
1994
|
end
|
1976
1995
|
|
1977
1996
|
resbody_construction = body_constr.for_branch(resbody).update_type_env do |env|
|
1978
|
-
assignments = {}
|
1997
|
+
assignments = {} #: Hash[Symbol, AST::Types::t]
|
1979
1998
|
|
1980
1999
|
case
|
1981
2000
|
when exn_classes && var_name && exn_types
|
@@ -2025,8 +2044,12 @@ module Steep
|
|
2025
2044
|
klasses, asgn, body = node.children
|
2026
2045
|
synthesize(klasses) if klasses
|
2027
2046
|
synthesize(asgn) if asgn
|
2028
|
-
|
2029
|
-
|
2047
|
+
if body
|
2048
|
+
body_type = synthesize(body, hint: hint).type
|
2049
|
+
add_typing(node, type: body_type)
|
2050
|
+
else
|
2051
|
+
add_typing(node, type: AST::Builtin.nil_type)
|
2052
|
+
end
|
2030
2053
|
end
|
2031
2054
|
|
2032
2055
|
when :ensure
|
@@ -2034,7 +2057,11 @@ module Steep
|
|
2034
2057
|
body, ensure_body = node.children
|
2035
2058
|
body_type = synthesize(body).type if body
|
2036
2059
|
synthesize(ensure_body) if ensure_body
|
2037
|
-
|
2060
|
+
if body_type
|
2061
|
+
add_typing(node, type: body_type)
|
2062
|
+
else
|
2063
|
+
add_typing(node, type: AST::Builtin.nil_type)
|
2064
|
+
end
|
2038
2065
|
end
|
2039
2066
|
|
2040
2067
|
when :masgn
|
@@ -2054,13 +2081,13 @@ module Steep
|
|
2054
2081
|
if method_type = (each.method_types || []).find {|type| type.block && type.block.type.params.first_param }
|
2055
2082
|
if block = method_type.block
|
2056
2083
|
if first_param = block.type.params.first_param
|
2057
|
-
var_type = first_param.type
|
2084
|
+
var_type = first_param.type #: AST::Types::t
|
2058
2085
|
end
|
2059
2086
|
end
|
2060
2087
|
end
|
2061
2088
|
end
|
2062
2089
|
end
|
2063
|
-
var_name = asgn.children[0]
|
2090
|
+
var_name = asgn.children[0] #: Symbol
|
2064
2091
|
|
2065
2092
|
if var_type
|
2066
2093
|
if body
|
@@ -2106,8 +2133,14 @@ module Steep
|
|
2106
2133
|
body_env, exit_env = truthy_env, falsy_env
|
2107
2134
|
when :until
|
2108
2135
|
exit_env, body_env = truthy_env, falsy_env
|
2136
|
+
else
|
2137
|
+
raise
|
2109
2138
|
end
|
2110
2139
|
|
2140
|
+
body_env or raise
|
2141
|
+
exit_env or raise
|
2142
|
+
|
2143
|
+
|
2111
2144
|
if body
|
2112
2145
|
pins = body_env.pin_local_variables(nil)
|
2113
2146
|
body_env = body_env.merge(local_variable_types: pins)
|
@@ -2131,7 +2164,7 @@ module Steep
|
|
2131
2164
|
yield_self do
|
2132
2165
|
cond, body = node.children
|
2133
2166
|
|
2134
|
-
_, cond_constr, = synthesize(cond)
|
2167
|
+
_, cond_constr, = synthesize(cond)
|
2135
2168
|
|
2136
2169
|
if body
|
2137
2170
|
for_loop =
|
@@ -2146,7 +2179,7 @@ module Steep
|
|
2146
2179
|
|
2147
2180
|
add_typing(node, type: AST::Builtin.nil_type, constr: constr)
|
2148
2181
|
else
|
2149
|
-
add_typing(node, type: AST::Builtin.nil_type, constr:
|
2182
|
+
add_typing(node, type: AST::Builtin.nil_type, constr: cond_constr)
|
2150
2183
|
end
|
2151
2184
|
end
|
2152
2185
|
|
@@ -2155,12 +2188,12 @@ module Steep
|
|
2155
2188
|
|
2156
2189
|
constr = self
|
2157
2190
|
begin_type, constr = if begin_node
|
2158
|
-
constr.synthesize(begin_node)
|
2191
|
+
constr.synthesize(begin_node).to_ary
|
2159
2192
|
else
|
2160
2193
|
[AST::Builtin.nil_type, constr]
|
2161
2194
|
end
|
2162
2195
|
end_type, constr = if end_node
|
2163
|
-
constr.synthesize(end_node)
|
2196
|
+
constr.synthesize(end_node).to_ary
|
2164
2197
|
else
|
2165
2198
|
[AST::Builtin.nil_type, constr]
|
2166
2199
|
end
|
@@ -2298,14 +2331,18 @@ module Steep
|
|
2298
2331
|
Steep.logger.error "Passing multiple args through Symbol#to_proc is not supported yet"
|
2299
2332
|
end
|
2300
2333
|
when value == nil
|
2301
|
-
|
2302
|
-
type
|
2303
|
-
|
2304
|
-
|
2305
|
-
|
2306
|
-
|
2307
|
-
|
2308
|
-
|
2334
|
+
if block_type = method_context!.block_type
|
2335
|
+
type = AST::Types::Proc.new(
|
2336
|
+
type: block_type.type,
|
2337
|
+
location: nil,
|
2338
|
+
block: nil,
|
2339
|
+
self_type: block_type.self_type
|
2340
|
+
)
|
2341
|
+
if block_type.optional?
|
2342
|
+
type = AST::Types::Union.build(types: [type, AST::Builtin.nil_type])
|
2343
|
+
end
|
2344
|
+
else
|
2345
|
+
type = AST::Builtin.nil_type
|
2309
2346
|
end
|
2310
2347
|
end
|
2311
2348
|
|
@@ -2328,9 +2365,12 @@ module Steep
|
|
2328
2365
|
|
2329
2366
|
type, constr = synthesize(rhs, hint: hint)
|
2330
2367
|
|
2331
|
-
var_type =
|
2332
|
-
|
2333
|
-
|
2368
|
+
var_type =
|
2369
|
+
if class_vars = module_context.class_variables
|
2370
|
+
if ty = class_vars[name]
|
2371
|
+
checker.factory.type(ty)
|
2372
|
+
end
|
2373
|
+
end
|
2334
2374
|
|
2335
2375
|
if var_type
|
2336
2376
|
result = constr.check_relation(sub_type: type, super_type: var_type)
|
@@ -2352,10 +2392,13 @@ module Steep
|
|
2352
2392
|
end
|
2353
2393
|
|
2354
2394
|
when :cvar
|
2355
|
-
name = node.children[0]
|
2356
|
-
var_type =
|
2357
|
-
|
2358
|
-
|
2395
|
+
name = node.children[0] #: Symbol
|
2396
|
+
var_type =
|
2397
|
+
if cvs = module_context.class_variables
|
2398
|
+
if ty = cvs[name]
|
2399
|
+
checker.factory.type(ty)
|
2400
|
+
end
|
2401
|
+
end
|
2359
2402
|
|
2360
2403
|
if var_type
|
2361
2404
|
add_typing node, type: var_type
|
@@ -2383,7 +2426,7 @@ module Steep
|
|
2383
2426
|
end
|
2384
2427
|
|
2385
2428
|
when :args
|
2386
|
-
constr = self
|
2429
|
+
constr = self #: TypeConstruction
|
2387
2430
|
|
2388
2431
|
each_child_node(node) do |child|
|
2389
2432
|
_, constr = constr.synthesize(child)
|
@@ -2396,7 +2439,7 @@ module Steep
|
|
2396
2439
|
# @type var as_type: AST::Node::TypeAssertion
|
2397
2440
|
asserted_node, as_type = node.children
|
2398
2441
|
|
2399
|
-
if type = as_type.type?(module_context
|
2442
|
+
if type = as_type.type?(module_context.nesting, checker.factory, [])
|
2400
2443
|
actual_type, constr = synthesize(asserted_node, hint: type)
|
2401
2444
|
|
2402
2445
|
if no_subtyping?(sub_type: type, super_type: actual_type) && no_subtyping?(sub_type: actual_type, super_type: type)
|
@@ -2426,6 +2469,9 @@ module Steep
|
|
2426
2469
|
constr.add_typing(node, type: type)
|
2427
2470
|
end
|
2428
2471
|
|
2472
|
+
when :forwarded_args, :forward_arg
|
2473
|
+
add_typing(node, type: AST::Builtin.any_type)
|
2474
|
+
|
2429
2475
|
else
|
2430
2476
|
typing.add_error(Diagnostic::Ruby::UnsupportedSyntax.new(node: node))
|
2431
2477
|
add_typing(node, type: AST::Builtin.any_type)
|
@@ -2439,7 +2485,7 @@ module Steep
|
|
2439
2485
|
end
|
2440
2486
|
rescue RBS::BaseError => exn
|
2441
2487
|
Steep.logger.warn { "Unexpected RBS error: #{exn.message}" }
|
2442
|
-
exn.backtrace
|
2488
|
+
exn.backtrace&.each {|loc| Steep.logger.warn " #{loc}" }
|
2443
2489
|
typing.add_error(Diagnostic::Ruby::UnexpectedError.new(node: node, error: exn))
|
2444
2490
|
type_any_rec(node)
|
2445
2491
|
rescue StandardError => exn
|
@@ -2466,7 +2512,7 @@ module Steep
|
|
2466
2512
|
when :send
|
2467
2513
|
yield_self do
|
2468
2514
|
if self_class?(node)
|
2469
|
-
module_type = expand_alias(module_context
|
2515
|
+
module_type = expand_alias(module_context.module_type)
|
2470
2516
|
type = if module_type.is_a?(AST::Types::Name::Singleton)
|
2471
2517
|
AST::Types::Name::Singleton.new(name: module_type.name)
|
2472
2518
|
else
|
@@ -2482,7 +2528,7 @@ module Steep
|
|
2482
2528
|
yield_self do
|
2483
2529
|
send_type, constr =
|
2484
2530
|
if self_class?(node)
|
2485
|
-
module_type = expand_alias(module_context
|
2531
|
+
module_type = expand_alias(module_context.module_type)
|
2486
2532
|
type = if module_type.is_a?(AST::Types::Name::Singleton)
|
2487
2533
|
AST::Types::Name::Singleton.new(name: module_type.name)
|
2488
2534
|
else
|
@@ -2501,6 +2547,7 @@ module Steep
|
|
2501
2547
|
yield_self do
|
2502
2548
|
send_node, params, body = node.children
|
2503
2549
|
if send_node.type == :lambda
|
2550
|
+
# @type var node: Parser::AST::Node & Parser::AST::_BlockNode
|
2504
2551
|
type_lambda(node, params_node: params, body_node: body, type_hint: hint)
|
2505
2552
|
else
|
2506
2553
|
type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend, tapp: tapp)
|
@@ -2519,6 +2566,7 @@ module Steep
|
|
2519
2566
|
params = Parser::AST::Node.new(:args, arg_nodes)
|
2520
2567
|
|
2521
2568
|
if send_node.type == :lambda
|
2569
|
+
# @type var node: Parser::AST::Node & Parser::AST::_BlockNode
|
2522
2570
|
type_lambda(node, params_node: params, body_node: body, type_hint: hint)
|
2523
2571
|
else
|
2524
2572
|
type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend, tapp: tapp)
|
@@ -2632,7 +2680,7 @@ module Steep
|
|
2632
2680
|
hint = masgn.hint_for_mlhs(lhs, context.type_env)
|
2633
2681
|
|
2634
2682
|
rhs_type, lhs_constr = try_tuple_type!(rhs, hint: hint).to_ary
|
2635
|
-
rhs_type = deep_expand_alias(rhs_type)
|
2683
|
+
rhs_type = deep_expand_alias(rhs_type) || rhs_type
|
2636
2684
|
|
2637
2685
|
falsys, truthys = partition_flatten_types(rhs_type) do |type|
|
2638
2686
|
type.is_a?(AST::Types::Nil) || (type.is_a?(AST::Types::Literal) && type.value == false)
|
@@ -2680,6 +2728,57 @@ module Steep
|
|
2680
2728
|
constr.add_typing(node, type: truthy_rhs_type)
|
2681
2729
|
end
|
2682
2730
|
|
2731
|
+
def synthesize_constant_decl(node, parent_node, constant_name, &block)
|
2732
|
+
const_name = module_name_from_node(parent_node, constant_name)
|
2733
|
+
|
2734
|
+
if const_name && type = context.type_env.annotated_constant(const_name)
|
2735
|
+
# const-type annotation wins
|
2736
|
+
if node
|
2737
|
+
constr = synthesize_children(node)
|
2738
|
+
type, constr = constr.add_typing(node, type: type)
|
2739
|
+
[type, constr, nil]
|
2740
|
+
else
|
2741
|
+
[type, self, nil]
|
2742
|
+
end
|
2743
|
+
else
|
2744
|
+
if parent_node
|
2745
|
+
synthesize_constant(node, parent_node, constant_name, &block)
|
2746
|
+
else
|
2747
|
+
if nesting
|
2748
|
+
if parent_nesting = nesting[1]
|
2749
|
+
if constant = context.type_env.constant_env.resolver.table.children(parent_nesting)&.fetch(constant_name, nil)
|
2750
|
+
return [checker.factory.type(constant.type), self, constant.name]
|
2751
|
+
end
|
2752
|
+
end
|
2753
|
+
|
2754
|
+
if block_given?
|
2755
|
+
yield
|
2756
|
+
else
|
2757
|
+
if node
|
2758
|
+
typing.add_error(
|
2759
|
+
Diagnostic::Ruby::UnknownConstant.new(node: node, name: constant_name)
|
2760
|
+
)
|
2761
|
+
end
|
2762
|
+
end
|
2763
|
+
|
2764
|
+
constr = self #: TypeConstruction
|
2765
|
+
if node
|
2766
|
+
_, constr = add_typing(node, type: AST::Builtin.any_type)
|
2767
|
+
end
|
2768
|
+
|
2769
|
+
[
|
2770
|
+
AST::Builtin.any_type,
|
2771
|
+
constr,
|
2772
|
+
nil
|
2773
|
+
]
|
2774
|
+
else
|
2775
|
+
# No neesting
|
2776
|
+
synthesize_constant(node, nil, constant_name, &block)
|
2777
|
+
end
|
2778
|
+
end
|
2779
|
+
end
|
2780
|
+
end
|
2781
|
+
|
2683
2782
|
def synthesize_constant(node, parent_node, constant_name)
|
2684
2783
|
const_name = module_name_from_node(parent_node, constant_name)
|
2685
2784
|
|
@@ -2795,7 +2894,7 @@ module Steep
|
|
2795
2894
|
|
2796
2895
|
block_constr.typing.add_context_for_body(node, context: block_constr.context)
|
2797
2896
|
|
2798
|
-
params.
|
2897
|
+
params.each_single_param do |param|
|
2799
2898
|
_, block_constr = block_constr.synthesize(param.node, hint: param.type)
|
2800
2899
|
end
|
2801
2900
|
|
@@ -2843,8 +2942,13 @@ module Steep
|
|
2843
2942
|
Interface::Substitution.build([], [], self_type: block_constr.self_type)
|
2844
2943
|
)
|
2845
2944
|
|
2846
|
-
if expected_block_type = block_constr.block_context
|
2847
|
-
type_vars = expected_block_type.free_variables
|
2945
|
+
if expected_block_type = block_constr.block_context!.body_type
|
2946
|
+
type_vars = expected_block_type.free_variables.filter_map do |var|
|
2947
|
+
case var
|
2948
|
+
when Symbol
|
2949
|
+
var
|
2950
|
+
end
|
2951
|
+
end
|
2848
2952
|
subst = Interface::Substitution.build(type_vars, type_vars.map { AST::Builtin.any_type })
|
2849
2953
|
expected_block_type = expected_block_type.subst(subst)
|
2850
2954
|
|
@@ -2879,7 +2983,7 @@ module Steep
|
|
2879
2983
|
end
|
2880
2984
|
|
2881
2985
|
def synthesize_children(node, skips: [])
|
2882
|
-
skips = Set.new.compare_by_identity.merge(skips)
|
2986
|
+
skips = Set.new.compare_by_identity.merge(skips).delete(nil)
|
2883
2987
|
|
2884
2988
|
# @type var constr: TypeConstruction
|
2885
2989
|
constr = self
|
@@ -2902,8 +3006,11 @@ module Steep
|
|
2902
3006
|
return false unless call.node.type == :send || call.node.type == :csend
|
2903
3007
|
return false unless call.pure? || KNOWN_PURE_METHODS.superset?(Set.new(call.method_decls.map(&:method_name)))
|
2904
3008
|
|
2905
|
-
[
|
2906
|
-
|
3009
|
+
argishes = [*arguments]
|
3010
|
+
argishes << receiver if receiver
|
3011
|
+
|
3012
|
+
argishes.all? do |node|
|
3013
|
+
value_node?(node) || context.type_env[node]
|
2907
3014
|
end
|
2908
3015
|
end
|
2909
3016
|
|
@@ -2944,7 +3051,11 @@ module Steep
|
|
2944
3051
|
end
|
2945
3052
|
else
|
2946
3053
|
constr = constr.update_type_env do |env|
|
2947
|
-
|
3054
|
+
if receiver
|
3055
|
+
env.invalidate_pure_node(receiver)
|
3056
|
+
else
|
3057
|
+
env
|
3058
|
+
end
|
2948
3059
|
end
|
2949
3060
|
end
|
2950
3061
|
end
|
@@ -2955,13 +3066,14 @@ module Steep
|
|
2955
3066
|
call = call.with_return_type(optional_type)
|
2956
3067
|
end
|
2957
3068
|
else
|
2958
|
-
errors = []
|
3069
|
+
errors = [] #: Array[Diagnostic::Ruby::Base]
|
2959
3070
|
|
2960
3071
|
skips = [receiver]
|
2961
3072
|
skips << node.children[0] if node.type == :block
|
2962
3073
|
|
2963
3074
|
constr = synthesize_children(node, skips: skips)
|
2964
3075
|
if block_params
|
3076
|
+
# @type var node: Parser::AST::Node & Parser::AST::_BlockNode
|
2965
3077
|
block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
|
2966
3078
|
|
2967
3079
|
constr.type_block_without_hint(
|
@@ -2982,7 +3094,7 @@ module Steep
|
|
2982
3094
|
)
|
2983
3095
|
call = TypeInference::MethodCall::Error.new(
|
2984
3096
|
node: node,
|
2985
|
-
context: context.
|
3097
|
+
context: context.call_context,
|
2986
3098
|
method_name: method_name,
|
2987
3099
|
receiver_type: receiver_type,
|
2988
3100
|
errors: errors
|
@@ -2991,7 +3103,7 @@ module Steep
|
|
2991
3103
|
|
2992
3104
|
constr.add_call(call)
|
2993
3105
|
else
|
2994
|
-
skips = []
|
3106
|
+
skips = [] #: Array[Parser::AST::Node?]
|
2995
3107
|
skips << receiver if receiver
|
2996
3108
|
skips << node.children[0] if node.type == :block
|
2997
3109
|
skips << block_params if block_params
|
@@ -2999,6 +3111,7 @@ module Steep
|
|
2999
3111
|
|
3000
3112
|
constr = synthesize_children(node, skips: skips)
|
3001
3113
|
if block_params
|
3114
|
+
# @type var node: Parser::AST::Node & Parser::AST::_BlockNode
|
3002
3115
|
block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
|
3003
3116
|
|
3004
3117
|
constr.type_block_without_hint(
|
@@ -3023,7 +3136,7 @@ module Steep
|
|
3023
3136
|
constr.add_call(
|
3024
3137
|
TypeInference::MethodCall::NoMethodError.new(
|
3025
3138
|
node: node,
|
3026
|
-
context: context.
|
3139
|
+
context: context.call_context,
|
3027
3140
|
method_name: method_name,
|
3028
3141
|
receiver_type: receiver_type,
|
3029
3142
|
error: Diagnostic::Ruby::NoMethod.new(node: node, method: method_name, type: interface&.type || receiver_type)
|
@@ -3070,46 +3183,65 @@ module Steep
|
|
3070
3183
|
receiver_type = checker.factory.deep_expand_alias(recv_type)
|
3071
3184
|
private = receiver.nil? || receiver.type == :self
|
3072
3185
|
|
3073
|
-
type, constr =
|
3074
|
-
|
3075
|
-
|
3076
|
-
|
3077
|
-
when AST::Types::Any
|
3078
|
-
constr = constr.synthesize_children(node, skips: [receiver])
|
3079
|
-
constr.add_call(
|
3080
|
-
TypeInference::MethodCall::Untyped.new(
|
3081
|
-
node: node,
|
3082
|
-
context: context.method_context,
|
3083
|
-
method_name: method_name
|
3084
|
-
)
|
3085
|
-
)
|
3186
|
+
type, constr =
|
3187
|
+
case receiver_type
|
3188
|
+
when nil
|
3189
|
+
raise
|
3086
3190
|
|
3087
|
-
|
3088
|
-
|
3089
|
-
|
3090
|
-
|
3091
|
-
|
3092
|
-
|
3093
|
-
|
3094
|
-
|
3095
|
-
|
3096
|
-
|
3097
|
-
|
3098
|
-
|
3099
|
-
|
3100
|
-
|
3101
|
-
|
3102
|
-
|
3103
|
-
|
3104
|
-
|
3105
|
-
|
3106
|
-
|
3107
|
-
|
3108
|
-
|
3109
|
-
|
3110
|
-
|
3111
|
-
|
3112
|
-
|
3191
|
+
when AST::Types::Any
|
3192
|
+
case node.type
|
3193
|
+
when :block, :numblock
|
3194
|
+
# @type var node: Parser::AST::Node & Parser::AST::_BlockNode
|
3195
|
+
block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
|
3196
|
+
block_params or raise
|
3197
|
+
|
3198
|
+
constr = constr.synthesize_children(node.children[0])
|
3199
|
+
|
3200
|
+
constr.type_block_without_hint(
|
3201
|
+
node: node,
|
3202
|
+
block_params: TypeInference::BlockParams.from_node(block_params, annotations: block_annotations),
|
3203
|
+
block_annotations: block_annotations,
|
3204
|
+
block_body: block_body
|
3205
|
+
) do |error|
|
3206
|
+
constr.typing.errors << error
|
3207
|
+
end
|
3208
|
+
else
|
3209
|
+
constr = constr.synthesize_children(node, skips: [receiver])
|
3210
|
+
end
|
3211
|
+
|
3212
|
+
constr.add_call(
|
3213
|
+
TypeInference::MethodCall::Untyped.new(
|
3214
|
+
node: node,
|
3215
|
+
context: context.call_context,
|
3216
|
+
method_name: method_name
|
3217
|
+
)
|
3218
|
+
)
|
3219
|
+
else
|
3220
|
+
if interface = calculate_interface(receiver_type, private: private)
|
3221
|
+
constr.type_send_interface(
|
3222
|
+
node,
|
3223
|
+
interface: interface,
|
3224
|
+
receiver: receiver,
|
3225
|
+
receiver_type: receiver_type,
|
3226
|
+
method_name: method_name,
|
3227
|
+
arguments: arguments,
|
3228
|
+
block_params: block_params,
|
3229
|
+
block_body: block_body,
|
3230
|
+
tapp: tapp
|
3231
|
+
)
|
3232
|
+
else
|
3233
|
+
constr = constr.synthesize_children(node, skips: [receiver])
|
3234
|
+
constr.add_call(
|
3235
|
+
TypeInference::MethodCall::NoMethodError.new(
|
3236
|
+
node: node,
|
3237
|
+
context: context.call_context,
|
3238
|
+
method_name: method_name,
|
3239
|
+
receiver_type: receiver_type,
|
3240
|
+
error: Diagnostic::Ruby::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
3241
|
+
)
|
3242
|
+
)
|
3243
|
+
end
|
3244
|
+
end
|
3113
3245
|
|
3114
3246
|
Pair.new(type: type, constr: constr)
|
3115
3247
|
end
|
@@ -3117,8 +3249,8 @@ module Steep
|
|
3117
3249
|
def builder_config
|
3118
3250
|
Interface::Builder::Config.new(
|
3119
3251
|
self_type: self_type,
|
3120
|
-
class_type: module_context
|
3121
|
-
instance_type: module_context
|
3252
|
+
class_type: module_context.module_type,
|
3253
|
+
instance_type: module_context.instance_type,
|
3122
3254
|
variable_bounds: variable_context.upper_bounds
|
3123
3255
|
)
|
3124
3256
|
end
|
@@ -3173,7 +3305,7 @@ module Steep
|
|
3173
3305
|
_, constr = add_typing(node, type: type)
|
3174
3306
|
call = TypeInference::MethodCall::Special.new(
|
3175
3307
|
node: node,
|
3176
|
-
context: constr.context.
|
3308
|
+
context: constr.context.call_context,
|
3177
3309
|
method_name: decl.method_name.method_name,
|
3178
3310
|
receiver_type: receiver_type,
|
3179
3311
|
actual_method_type: method_type.with(type: method_type.type.with(return_type: type)),
|
@@ -3197,7 +3329,7 @@ module Steep
|
|
3197
3329
|
_, constr = add_typing(node, type: type)
|
3198
3330
|
call = TypeInference::MethodCall::Special.new(
|
3199
3331
|
node: node,
|
3200
|
-
context: constr.context.
|
3332
|
+
context: constr.context.call_context,
|
3201
3333
|
method_name: decl.method_name.method_name,
|
3202
3334
|
receiver_type: receiver_type,
|
3203
3335
|
actual_method_type: method_type.with(type: method_type.type.with(return_type: type)),
|
@@ -3214,7 +3346,7 @@ module Steep
|
|
3214
3346
|
end
|
3215
3347
|
|
3216
3348
|
def type_method_call(node, method_name:, receiver_type:, method:, arguments:, block_params:, block_body:, tapp:)
|
3217
|
-
node_range = node.loc.expression.
|
3349
|
+
node_range = node.loc.expression.to_range
|
3218
3350
|
|
3219
3351
|
# @type var fails: Array[[TypeInference::MethodCall::t, TypeConstruction]]
|
3220
3352
|
fails = []
|
@@ -3327,11 +3459,11 @@ module Steep
|
|
3327
3459
|
end
|
3328
3460
|
end
|
3329
3461
|
|
3330
|
-
def type_check_args(args, constraints, errors)
|
3462
|
+
def type_check_args(method_name, args, constraints, errors)
|
3331
3463
|
# @type var constr: TypeConstruction
|
3332
3464
|
constr = self
|
3333
3465
|
|
3334
|
-
es = args.each do |arg|
|
3466
|
+
forwarded_args, es = args.each do |arg|
|
3335
3467
|
case arg
|
3336
3468
|
when TypeInference::SendArgs::PositionalArgs::NodeParamPair
|
3337
3469
|
_, constr = constr.type_check_argument(
|
@@ -3404,20 +3536,48 @@ module Steep
|
|
3404
3536
|
|
3405
3537
|
when TypeInference::SendArgs::KeywordArgs::MissingKeyword
|
3406
3538
|
# ignore
|
3539
|
+
|
3407
3540
|
else
|
3408
|
-
raise arg.inspect
|
3541
|
+
raise (_ = arg).inspect
|
3409
3542
|
end
|
3410
3543
|
end
|
3411
3544
|
|
3412
3545
|
errors.push(*es)
|
3413
3546
|
|
3547
|
+
if forwarded_args
|
3548
|
+
method_name or raise "method_name cannot be nil if `forwarded_args` is given, because proc/block doesn't support `...` arg"
|
3549
|
+
|
3550
|
+
(params, block = context.method_context&.forward_arg_type) or raise
|
3551
|
+
|
3552
|
+
checker.with_context(self_type: self_type, instance_type: context.module_context.instance_type, class_type: context.module_context.module_type, constraints: constraints) do
|
3553
|
+
result = checker.check_method_params(
|
3554
|
+
:"... (argument forwarding)",
|
3555
|
+
Subtyping::Relation.new(
|
3556
|
+
sub_type: forwarded_args.params,
|
3557
|
+
super_type: params
|
3558
|
+
)
|
3559
|
+
)
|
3560
|
+
|
3561
|
+
if result.failure?
|
3562
|
+
errors.push(
|
3563
|
+
Diagnostic::Ruby::IncompatibleArgumentForwarding.new(
|
3564
|
+
method_name: method_name,
|
3565
|
+
node: forwarded_args.node,
|
3566
|
+
params_pair: [params, forwarded_args.params],
|
3567
|
+
result: result
|
3568
|
+
)
|
3569
|
+
)
|
3570
|
+
end
|
3571
|
+
end
|
3572
|
+
end
|
3573
|
+
|
3414
3574
|
constr
|
3415
3575
|
end
|
3416
3576
|
|
3417
3577
|
def try_method_type(node, receiver_type:, method_name:, method_type:, arguments:, block_params:, block_body:, tapp:)
|
3418
3578
|
constr = self
|
3419
3579
|
|
3420
|
-
if tapp && type_args = tapp.types?(module_context
|
3580
|
+
if tapp && type_args = tapp.types?(module_context.nesting, checker.factory, [])
|
3421
3581
|
type_arity = method_type.type_params.size
|
3422
3582
|
type_param_names = method_type.type_params.map(&:name)
|
3423
3583
|
|
@@ -3477,7 +3637,7 @@ module Steep
|
|
3477
3637
|
)
|
3478
3638
|
end
|
3479
3639
|
|
3480
|
-
type_params = []
|
3640
|
+
type_params = [] #: Array[Interface::TypeParam]
|
3481
3641
|
type_param_names.clear
|
3482
3642
|
else
|
3483
3643
|
# Infer type application
|
@@ -3499,12 +3659,12 @@ module Steep
|
|
3499
3659
|
constraints = Subtyping::Constraints.new(unknowns: type_params.map(&:name))
|
3500
3660
|
ccontext = Subtyping::Constraints::Context.new(
|
3501
3661
|
self_type: self_type,
|
3502
|
-
instance_type: module_context
|
3503
|
-
class_type: module_context
|
3662
|
+
instance_type: module_context.instance_type,
|
3663
|
+
class_type: module_context.module_type,
|
3504
3664
|
variance: variance
|
3505
3665
|
)
|
3506
3666
|
|
3507
|
-
upper_bounds = {}
|
3667
|
+
upper_bounds = {} #: Hash[Symbol, AST::Types::t]
|
3508
3668
|
|
3509
3669
|
type_params.each do |param|
|
3510
3670
|
if ub = param.upper_bound
|
@@ -3514,11 +3674,14 @@ module Steep
|
|
3514
3674
|
end
|
3515
3675
|
|
3516
3676
|
checker.push_variable_bounds(upper_bounds) do
|
3677
|
+
# @type block: [TypeInference::MethodCall::t, TypeConstruction]
|
3678
|
+
|
3517
3679
|
# @type var errors: Array[Diagnostic::Ruby::Base]
|
3518
3680
|
errors = []
|
3519
3681
|
|
3520
3682
|
args = TypeInference::SendArgs.new(node: node, arguments: arguments, type: method_type)
|
3521
3683
|
constr = constr.type_check_args(
|
3684
|
+
method_name,
|
3522
3685
|
args,
|
3523
3686
|
constraints,
|
3524
3687
|
errors
|
@@ -3526,6 +3689,8 @@ module Steep
|
|
3526
3689
|
|
3527
3690
|
if block_params
|
3528
3691
|
# block is given
|
3692
|
+
# @type var node: Parser::AST::Node & Parser::AST::_BlockNode
|
3693
|
+
|
3529
3694
|
block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
|
3530
3695
|
block_params_ = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
|
3531
3696
|
|
@@ -3596,12 +3761,14 @@ module Steep
|
|
3596
3761
|
)
|
3597
3762
|
}
|
3598
3763
|
|
3764
|
+
method_type.block or raise
|
3765
|
+
|
3599
3766
|
if solved
|
3600
3767
|
# Ready for type check the body of the block
|
3601
3768
|
block_constr = block_constr.update_type_env {|env| env.subst(s) }
|
3602
3769
|
block_constr = block_constr.update_context {|context|
|
3603
3770
|
context.with(
|
3604
|
-
self_type: method_type.block
|
3771
|
+
self_type: method_type.block.self_type || context.self_type,
|
3605
3772
|
type_env: context.type_env.subst(s),
|
3606
3773
|
block_context: context.block_context&.subst(s),
|
3607
3774
|
break_context: context.break_context&.subst(s)
|
@@ -3708,6 +3875,21 @@ module Steep
|
|
3708
3875
|
arg = args.block_pass_arg
|
3709
3876
|
|
3710
3877
|
case
|
3878
|
+
when forwarded_args_node = args.forwarded_args_node
|
3879
|
+
(_, block = method_context!.forward_arg_type) or raise
|
3880
|
+
|
3881
|
+
method_block_type = method_type.block&.to_proc_type || AST::Builtin.nil_type
|
3882
|
+
forwarded_block_type = block&.to_proc_type || AST::Builtin.nil_type
|
3883
|
+
|
3884
|
+
if result = constr.no_subtyping?(sub_type: forwarded_block_type, super_type: method_block_type)
|
3885
|
+
errors << Diagnostic::Ruby::IncompatibleArgumentForwarding.new(
|
3886
|
+
method_name: method_name,
|
3887
|
+
node: forwarded_args_node,
|
3888
|
+
block_pair: [block, method_type.block],
|
3889
|
+
result: result
|
3890
|
+
)
|
3891
|
+
end
|
3892
|
+
|
3711
3893
|
when arg.compatible?
|
3712
3894
|
if arg.node
|
3713
3895
|
# Block pass (&block) is given
|
@@ -3770,7 +3952,10 @@ module Steep
|
|
3770
3952
|
)
|
3771
3953
|
|
3772
3954
|
when arg.unexpected_block?
|
3773
|
-
# Unexpected block is given
|
3955
|
+
# Unexpected block pass node is given
|
3956
|
+
|
3957
|
+
arg.node or raise
|
3958
|
+
|
3774
3959
|
method_type, solved, _ = apply_solution(errors, node: node, method_type: method_type) {
|
3775
3960
|
constraints.solution(checker, variables: method_type.free_variables, context: ccontext)
|
3776
3961
|
}
|
@@ -3791,7 +3976,7 @@ module Steep
|
|
3791
3976
|
call = if errors.empty?
|
3792
3977
|
TypeInference::MethodCall::Typed.new(
|
3793
3978
|
node: node,
|
3794
|
-
context: context.
|
3979
|
+
context: context.call_context,
|
3795
3980
|
receiver_type: receiver_type,
|
3796
3981
|
method_name: method_name,
|
3797
3982
|
actual_method_type: method_type,
|
@@ -3801,7 +3986,7 @@ module Steep
|
|
3801
3986
|
else
|
3802
3987
|
TypeInference::MethodCall::Error.new(
|
3803
3988
|
node: node,
|
3804
|
-
context: context.
|
3989
|
+
context: context.call_context,
|
3805
3990
|
receiver_type: receiver_type,
|
3806
3991
|
method_name: method_name,
|
3807
3992
|
return_type: return_type || method_type.type.return_type,
|
@@ -3871,7 +4056,7 @@ module Steep
|
|
3871
4056
|
|
3872
4057
|
block_type = block_constr.synthesize_block(node: node, block_type_hint: nil, block_body: block_body)
|
3873
4058
|
|
3874
|
-
if expected_block_type = block_constr.block_context
|
4059
|
+
if expected_block_type = block_constr.block_context!.body_type
|
3875
4060
|
block_constr.check_relation(sub_type: block_type, super_type: expected_block_type).else do |result|
|
3876
4061
|
Diagnostic::Ruby::BlockBodyTypeMismatch.new(
|
3877
4062
|
node: node,
|
@@ -3947,8 +4132,7 @@ module Steep
|
|
3947
4132
|
|
3948
4133
|
param_types_hash.delete_if {|name, _| SPECIAL_LVAR_NAMES.include?(name) }
|
3949
4134
|
|
3950
|
-
param_types = param_types_hash.each.with_object({}) do |pair, hash|
|
3951
|
-
# @type var hash: Hash[Symbol, [AST::Types::t, AST::Types::t?]]
|
4135
|
+
param_types = param_types_hash.each.with_object({}) do |pair, hash| #$ Hash[Symbol, [AST::Types::t, AST::Types::t?]]
|
3952
4136
|
name, type = pair
|
3953
4137
|
hash[name] = [type, nil]
|
3954
4138
|
end
|
@@ -4034,7 +4218,7 @@ module Steep
|
|
4034
4218
|
|
4035
4219
|
def synthesize_block(node:, block_type_hint:, block_body:)
|
4036
4220
|
if block_body
|
4037
|
-
body_type, _, context = synthesize(block_body, hint: block_context
|
4221
|
+
body_type, _, context = synthesize(block_body, hint: block_context&.body_type || block_type_hint)
|
4038
4222
|
|
4039
4223
|
range = block_body.loc.expression.end_pos..node.loc.end.begin_pos
|
4040
4224
|
typing.add_context(range, context: context)
|
@@ -4055,7 +4239,7 @@ module Steep
|
|
4055
4239
|
|
4056
4240
|
def union_type(*types)
|
4057
4241
|
raise if types.empty?
|
4058
|
-
AST::Types::Union.build(types: types)
|
4242
|
+
AST::Types::Union.build(types: types.compact)
|
4059
4243
|
end
|
4060
4244
|
|
4061
4245
|
def union_type_unify(*types)
|
@@ -4104,14 +4288,18 @@ module Steep
|
|
4104
4288
|
return unless member_decl_count == 1
|
4105
4289
|
|
4106
4290
|
expected_instance_method_names = (module_context.instance_definition&.methods || {}).each.with_object(Set[]) do |(name, method), set|
|
4107
|
-
if method.implemented_in
|
4108
|
-
|
4291
|
+
if method.implemented_in
|
4292
|
+
if method.implemented_in == module_context.instance_definition&.type_name
|
4293
|
+
set << name
|
4294
|
+
end
|
4109
4295
|
end
|
4110
4296
|
end
|
4111
4297
|
expected_module_method_names = (module_context.module_definition&.methods || {}).each.with_object(Set[]) do |(name, method), set|
|
4112
4298
|
if name != :new
|
4113
|
-
if method.implemented_in
|
4114
|
-
|
4299
|
+
if method.implemented_in
|
4300
|
+
if method.implemented_in == module_context.module_definition&.type_name
|
4301
|
+
set << name
|
4302
|
+
end
|
4115
4303
|
end
|
4116
4304
|
end
|
4117
4305
|
end
|
@@ -4188,18 +4376,20 @@ module Steep
|
|
4188
4376
|
end
|
4189
4377
|
|
4190
4378
|
def namespace_module?(node)
|
4191
|
-
|
4192
|
-
|
4193
|
-
|
4194
|
-
|
4195
|
-
|
4196
|
-
|
4197
|
-
|
4198
|
-
|
4199
|
-
|
4200
|
-
|
4201
|
-
|
4202
|
-
|
4379
|
+
# @type var nodes: Array[Parser::AST::Node]
|
4380
|
+
nodes =
|
4381
|
+
case node.type
|
4382
|
+
when :class, :module
|
4383
|
+
node.children.last&.yield_self {|child|
|
4384
|
+
if child.type == :begin
|
4385
|
+
child.children
|
4386
|
+
else
|
4387
|
+
[child]
|
4388
|
+
end
|
4389
|
+
} || []
|
4390
|
+
else
|
4391
|
+
return false
|
4392
|
+
end
|
4203
4393
|
|
4204
4394
|
!nodes.empty? && nodes.all? {|child| child.type == :class || child.type == :module}
|
4205
4395
|
end
|
@@ -4228,18 +4418,19 @@ module Steep
|
|
4228
4418
|
end
|
4229
4419
|
|
4230
4420
|
def select_flatten_types(type, &block)
|
4231
|
-
types = flatten_union(deep_expand_alias(type))
|
4421
|
+
types = flatten_union(deep_expand_alias(type) || type)
|
4232
4422
|
types.select(&block)
|
4233
4423
|
end
|
4234
4424
|
|
4235
4425
|
def partition_flatten_types(type, &block)
|
4236
|
-
types = flatten_union(deep_expand_alias(type))
|
4426
|
+
types = flatten_union(deep_expand_alias(type) || type)
|
4237
4427
|
types.partition(&block)
|
4238
4428
|
end
|
4239
4429
|
|
4240
4430
|
def flatten_array_elements(type)
|
4241
|
-
flatten_union(deep_expand_alias(type)).flat_map do |type|
|
4431
|
+
flatten_union(deep_expand_alias(type) || type).flat_map do |type|
|
4242
4432
|
if AST::Builtin::Array.instance_type?(type)
|
4433
|
+
# @type var type: AST::Types::Name::Instance
|
4243
4434
|
type.args
|
4244
4435
|
else
|
4245
4436
|
[type]
|
@@ -4248,7 +4439,12 @@ module Steep
|
|
4248
4439
|
end
|
4249
4440
|
|
4250
4441
|
def expand_alias(type, &block)
|
4251
|
-
checker.factory.expand_alias(type
|
4442
|
+
typ = checker.factory.expand_alias(type)
|
4443
|
+
if block
|
4444
|
+
yield(typ)
|
4445
|
+
else
|
4446
|
+
typ
|
4447
|
+
end
|
4252
4448
|
end
|
4253
4449
|
|
4254
4450
|
def test_literal_type(literal, hint)
|
@@ -4296,9 +4492,8 @@ module Steep
|
|
4296
4492
|
def try_tuple_type(array_node, hint)
|
4297
4493
|
raise unless array_node.type == :array
|
4298
4494
|
|
4299
|
-
constr = self
|
4300
|
-
|
4301
|
-
element_types = []
|
4495
|
+
constr = self #: TypeConstruction
|
4496
|
+
element_types = [] #: Array[AST::Types::t]
|
4302
4497
|
|
4303
4498
|
array_node.children.each_with_index do |child, index|
|
4304
4499
|
return if child.type == :splat
|
@@ -4380,11 +4575,14 @@ module Steep
|
|
4380
4575
|
instance_type: module_context.instance_type,
|
4381
4576
|
class_type: module_context.module_type
|
4382
4577
|
)
|
4383
|
-
|
4384
|
-
|
4385
|
-
|
4386
|
-
|
4387
|
-
|
4578
|
+
|
4579
|
+
variables = (type.free_variables + [var.name]).filter_map do |name|
|
4580
|
+
case name
|
4581
|
+
when Symbol
|
4582
|
+
name
|
4583
|
+
end
|
4584
|
+
end
|
4585
|
+
subst = constraints.solution(checker, variables: variables, context: context)
|
4388
4586
|
|
4389
4587
|
type.subst(subst)
|
4390
4588
|
end
|
@@ -4393,8 +4591,8 @@ module Steep
|
|
4393
4591
|
def try_array_type(node, hint)
|
4394
4592
|
element_hint = hint ? hint.args[0] : nil
|
4395
4593
|
|
4396
|
-
constr = self
|
4397
|
-
element_types = []
|
4594
|
+
constr = self #: TypeConstruction
|
4595
|
+
element_types = [] #: Array[AST::Types::t]
|
4398
4596
|
|
4399
4597
|
each_child_node(node) do |child|
|
4400
4598
|
case child.type
|
@@ -4425,24 +4623,24 @@ module Steep
|
|
4425
4623
|
def type_hash_record(hash_node, record_type)
|
4426
4624
|
raise unless hash_node.type == :hash || hash_node.type == :kwargs
|
4427
4625
|
|
4428
|
-
constr = self
|
4626
|
+
constr = self #: TypeConstruction
|
4429
4627
|
|
4430
4628
|
if record_type
|
4431
4629
|
hints = record_type.elements.dup
|
4432
4630
|
else
|
4433
|
-
hints = {}
|
4631
|
+
hints = {} #: Hash[AST::Types::Record::key, AST::Types::t]
|
4434
4632
|
end
|
4435
4633
|
|
4436
|
-
elems = {}
|
4634
|
+
elems = {} #: Hash[AST::Types::Record::key, AST::Types::t]
|
4437
4635
|
|
4438
4636
|
each_child_node(hash_node) do |child|
|
4439
4637
|
if child.type == :pair
|
4440
4638
|
case child.children[0].type
|
4441
4639
|
when :sym, :str, :int
|
4442
|
-
key_node = child.children[0]
|
4443
|
-
value_node = child.children[1]
|
4640
|
+
key_node = child.children[0] #: Parser::AST::Node
|
4641
|
+
value_node = child.children[1] #: Parser::AST::Node
|
4444
4642
|
|
4445
|
-
key = key_node.children[0]
|
4643
|
+
key = key_node.children[0] #: String | Symbol | Integer
|
4446
4644
|
|
4447
4645
|
_, constr = constr.synthesize(key_node, hint: AST::Types::Literal.new(value: key))
|
4448
4646
|
|
@@ -4471,14 +4669,10 @@ module Steep
|
|
4471
4669
|
constr.add_typing(hash_node, type: type)
|
4472
4670
|
end
|
4473
4671
|
|
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
4672
|
def type_hash(hash_node, hint:)
|
4481
|
-
|
4673
|
+
if hint
|
4674
|
+
hint = deep_expand_alias(hint)
|
4675
|
+
end
|
4482
4676
|
range = hash_node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
|
4483
4677
|
|
4484
4678
|
case hint
|
@@ -4499,10 +4693,11 @@ module Steep
|
|
4499
4693
|
end
|
4500
4694
|
end
|
4501
4695
|
|
4502
|
-
key_types = []
|
4503
|
-
value_types = []
|
4696
|
+
key_types = [] #: Array[AST::Types::t]
|
4697
|
+
value_types = [] #: Array[AST::Types::t]
|
4504
4698
|
|
4505
|
-
if AST::Builtin::Hash.instance_type?(hint)
|
4699
|
+
if hint && AST::Builtin::Hash.instance_type?(hint)
|
4700
|
+
# @type var hint: AST::Types::Name::Instance
|
4506
4701
|
key_hint, value_hint = hint.args
|
4507
4702
|
end
|
4508
4703
|
|
@@ -4511,7 +4706,7 @@ module Steep
|
|
4511
4706
|
value_hint || AST::Builtin.any_type
|
4512
4707
|
)
|
4513
4708
|
|
4514
|
-
constr = self
|
4709
|
+
constr = self #: TypeConstruction
|
4515
4710
|
|
4516
4711
|
if hash_node.children.empty?
|
4517
4712
|
key_types << key_hint if key_hint
|
@@ -4528,14 +4723,13 @@ module Steep
|
|
4528
4723
|
value_types << value_type
|
4529
4724
|
when :kwsplat
|
4530
4725
|
bypass_splat(elem) do |elem_|
|
4531
|
-
|
4532
|
-
|
4533
|
-
|
4534
|
-
|
4535
|
-
|
4726
|
+
constr.synthesize(elem_, hint: hint_hash).tap do |(type, _)|
|
4727
|
+
if AST::Builtin::Hash.instance_type?(type)
|
4728
|
+
# @type var type: AST::Types::Name::Instance
|
4729
|
+
key_types << type.args[0]
|
4730
|
+
value_types << type.args[1]
|
4731
|
+
end
|
4536
4732
|
end
|
4537
|
-
|
4538
|
-
pair
|
4539
4733
|
end
|
4540
4734
|
else
|
4541
4735
|
raise
|
@@ -4573,7 +4767,7 @@ module Steep
|
|
4573
4767
|
|
4574
4768
|
def save_typing
|
4575
4769
|
typing.save!
|
4576
|
-
with_new_typing(typing.parent)
|
4770
|
+
with_new_typing(typing.parent || raise)
|
4577
4771
|
end
|
4578
4772
|
|
4579
4773
|
def extract_outermost_call(node, var_name)
|