steep 0.1.0.pre2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +1 -1
- data/README.md +146 -33
- data/bin/smoke_runner.rb +43 -10
- data/lib/steep/ast/annotation/collection.rb +93 -0
- data/lib/steep/ast/annotation.rb +131 -0
- data/lib/steep/ast/buffer.rb +47 -0
- data/lib/steep/ast/location.rb +82 -0
- data/lib/steep/ast/method_type.rb +116 -0
- data/lib/steep/ast/signature/class.rb +33 -0
- data/lib/steep/ast/signature/const.rb +17 -0
- data/lib/steep/ast/signature/env.rb +123 -0
- data/lib/steep/ast/signature/extension.rb +21 -0
- data/lib/steep/ast/signature/gvar.rb +17 -0
- data/lib/steep/ast/signature/interface.rb +31 -0
- data/lib/steep/ast/signature/members.rb +71 -0
- data/lib/steep/ast/signature/module.rb +21 -0
- data/lib/steep/ast/type_params.rb +13 -0
- data/lib/steep/ast/types/any.rb +39 -0
- data/lib/steep/ast/types/bot.rb +39 -0
- data/lib/steep/ast/types/class.rb +35 -0
- data/lib/steep/ast/types/helper.rb +21 -0
- data/lib/steep/ast/types/instance.rb +39 -0
- data/lib/steep/ast/types/intersection.rb +74 -0
- data/lib/steep/ast/types/name.rb +124 -0
- data/lib/steep/ast/types/self.rb +39 -0
- data/lib/steep/ast/types/top.rb +39 -0
- data/lib/steep/ast/types/union.rb +74 -0
- data/lib/steep/ast/types/var.rb +57 -0
- data/lib/steep/ast/types/void.rb +35 -0
- data/lib/steep/cli.rb +28 -1
- data/lib/steep/drivers/annotations.rb +32 -0
- data/lib/steep/drivers/check.rb +53 -77
- data/lib/steep/drivers/scaffold.rb +303 -0
- data/lib/steep/drivers/utils/each_signature.rb +66 -0
- data/lib/steep/drivers/utils/validator.rb +115 -0
- data/lib/steep/drivers/validate.rb +39 -0
- data/lib/steep/errors.rb +291 -19
- data/lib/steep/interface/abstract.rb +44 -0
- data/lib/steep/interface/builder.rb +470 -0
- data/lib/steep/interface/instantiated.rb +126 -0
- data/lib/steep/interface/ivar_chain.rb +26 -0
- data/lib/steep/interface/method.rb +60 -0
- data/lib/steep/{interface.rb → interface/method_type.rb} +111 -100
- data/lib/steep/interface/substitution.rb +65 -0
- data/lib/steep/module_name.rb +116 -0
- data/lib/steep/parser.rb +1314 -814
- data/lib/steep/parser.y +536 -175
- data/lib/steep/source.rb +220 -25
- data/lib/steep/subtyping/check.rb +673 -0
- data/lib/steep/subtyping/constraints.rb +275 -0
- data/lib/steep/subtyping/relation.rb +41 -0
- data/lib/steep/subtyping/result.rb +126 -0
- data/lib/steep/subtyping/trace.rb +48 -0
- data/lib/steep/subtyping/variable_occurrence.rb +49 -0
- data/lib/steep/subtyping/variable_variance.rb +69 -0
- data/lib/steep/type_construction.rb +1630 -524
- data/lib/steep/type_inference/block_params.rb +100 -0
- data/lib/steep/type_inference/constant_env.rb +55 -0
- data/lib/steep/type_inference/send_args.rb +222 -0
- data/lib/steep/type_inference/type_env.rb +226 -0
- data/lib/steep/type_name.rb +27 -7
- data/lib/steep/typing.rb +4 -0
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +71 -16
- data/smoke/and/a.rb +4 -2
- data/smoke/array/a.rb +4 -5
- data/smoke/array/b.rb +4 -4
- data/smoke/block/a.rb +2 -2
- data/smoke/block/a.rbi +2 -0
- data/smoke/block/b.rb +15 -0
- data/smoke/case/a.rb +3 -3
- data/smoke/class/a.rb +3 -3
- data/smoke/class/b.rb +0 -2
- data/smoke/class/d.rb +2 -2
- data/smoke/class/e.rb +1 -1
- data/smoke/class/f.rb +2 -2
- data/smoke/class/g.rb +8 -0
- data/smoke/const/a.rb +3 -3
- data/smoke/dstr/a.rb +1 -1
- data/smoke/ensure/a.rb +22 -0
- data/smoke/enumerator/a.rb +6 -6
- data/smoke/enumerator/b.rb +22 -0
- data/smoke/extension/a.rb +2 -2
- data/smoke/extension/b.rb +3 -3
- data/smoke/extension/c.rb +1 -1
- data/smoke/hello/hello.rb +2 -2
- data/smoke/if/a.rb +4 -2
- data/smoke/kwbegin/a.rb +8 -0
- data/smoke/literal/a.rb +5 -5
- data/smoke/method/a.rb +5 -5
- data/smoke/method/a.rbi +4 -0
- data/smoke/method/b.rb +29 -0
- data/smoke/module/a.rb +3 -3
- data/smoke/module/a.rbi +9 -0
- data/smoke/module/b.rb +2 -2
- data/smoke/module/c.rb +1 -1
- data/smoke/module/d.rb +5 -0
- data/smoke/module/e.rb +13 -0
- data/smoke/module/f.rb +13 -0
- data/smoke/rescue/a.rb +62 -0
- data/smoke/super/a.rb +2 -2
- data/smoke/type_case/a.rb +35 -0
- data/smoke/yield/a.rb +2 -2
- data/stdlib/builtin.rbi +463 -24
- data/steep.gemspec +3 -2
- metadata +91 -29
- data/lib/steep/annotation.rb +0 -223
- data/lib/steep/signature/class.rb +0 -450
- data/lib/steep/signature/extension.rb +0 -51
- data/lib/steep/signature/interface.rb +0 -49
- data/lib/steep/types/any.rb +0 -31
- data/lib/steep/types/class.rb +0 -27
- data/lib/steep/types/instance.rb +0 -27
- data/lib/steep/types/merge.rb +0 -32
- data/lib/steep/types/name.rb +0 -57
- data/lib/steep/types/union.rb +0 -42
- data/lib/steep/types/var.rb +0 -38
- data/lib/steep/types.rb +0 -4
@@ -1,8 +1,46 @@
|
|
1
1
|
module Steep
|
2
2
|
class TypeConstruction
|
3
|
+
module Types
|
4
|
+
module_function
|
5
|
+
|
6
|
+
def any
|
7
|
+
AST::Types::Any.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def symbol_instance
|
11
|
+
AST::Types::Name.new_instance(name: "::Symbol")
|
12
|
+
end
|
13
|
+
|
14
|
+
def nil_instance
|
15
|
+
AST::Types::Name.new_instance(name: "::NilClass")
|
16
|
+
end
|
17
|
+
|
18
|
+
def string_instance
|
19
|
+
AST::Types::Name.new_instance(name: "::String")
|
20
|
+
end
|
21
|
+
|
22
|
+
def array_instance(type)
|
23
|
+
AST::Types::Name.new_instance(name: "::Array", args: [type])
|
24
|
+
end
|
25
|
+
|
26
|
+
def hash_instance(key, value)
|
27
|
+
AST::Types::Name.new_instance(name: "::Hash", args: [key, value])
|
28
|
+
end
|
29
|
+
|
30
|
+
def range_instance(type)
|
31
|
+
AST::Types::Name.new_instance(name: "::Range", args: [type])
|
32
|
+
end
|
33
|
+
|
34
|
+
def boolean?(type)
|
35
|
+
type == AST::Types::Name.new_interface(name: :_Boolean)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
3
39
|
class MethodContext
|
4
40
|
attr_reader :name
|
5
41
|
attr_reader :method
|
42
|
+
attr_reader :method_type
|
43
|
+
attr_reader :return_type
|
6
44
|
attr_reader :constructor
|
7
45
|
|
8
46
|
def initialize(name:, method:, method_type:, return_type:, constructor:)
|
@@ -13,30 +51,30 @@ module Steep
|
|
13
51
|
@constructor = constructor
|
14
52
|
end
|
15
53
|
|
16
|
-
def return_type
|
17
|
-
@return_type || method_type&.return_type
|
18
|
-
end
|
19
|
-
|
20
54
|
def block_type
|
21
55
|
method_type&.block
|
22
56
|
end
|
23
57
|
|
24
|
-
def
|
25
|
-
|
58
|
+
def super_method
|
59
|
+
method&.super_method
|
26
60
|
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class BlockContext
|
64
|
+
attr_reader :body_type
|
27
65
|
|
28
|
-
def
|
29
|
-
|
66
|
+
def initialize(body_type:)
|
67
|
+
@body_type = body_type
|
30
68
|
end
|
31
69
|
end
|
32
70
|
|
33
|
-
class
|
71
|
+
class BreakContext
|
34
72
|
attr_reader :break_type
|
35
|
-
attr_reader :
|
73
|
+
attr_reader :next_type
|
36
74
|
|
37
|
-
def initialize(break_type:,
|
75
|
+
def initialize(break_type:, next_type:)
|
38
76
|
@break_type = break_type
|
39
|
-
@
|
77
|
+
@next_type = next_type
|
40
78
|
end
|
41
79
|
end
|
42
80
|
|
@@ -45,726 +83,1685 @@ module Steep
|
|
45
83
|
attr_reader :module_type
|
46
84
|
attr_reader :defined_instance_methods
|
47
85
|
attr_reader :defined_module_methods
|
48
|
-
attr_reader :
|
86
|
+
attr_reader :const_env
|
87
|
+
attr_reader :implement_name
|
88
|
+
attr_reader :current_namespace
|
49
89
|
|
50
|
-
def initialize(instance_type:, module_type:,
|
90
|
+
def initialize(instance_type:, module_type:, implement_name:, current_namespace:, const_env:)
|
51
91
|
@instance_type = instance_type
|
52
92
|
@module_type = module_type
|
53
93
|
@defined_instance_methods = Set.new
|
54
94
|
@defined_module_methods = Set.new
|
55
|
-
@
|
95
|
+
@implement_name = implement_name
|
96
|
+
@current_namespace = current_namespace
|
97
|
+
@const_env = const_env
|
56
98
|
end
|
57
99
|
end
|
58
100
|
|
59
|
-
attr_reader :
|
101
|
+
attr_reader :checker
|
60
102
|
attr_reader :source
|
61
103
|
attr_reader :annotations
|
62
|
-
attr_reader :var_types
|
63
|
-
attr_reader :ivar_types
|
64
104
|
attr_reader :typing
|
65
105
|
attr_reader :method_context
|
66
106
|
attr_reader :block_context
|
67
107
|
attr_reader :module_context
|
68
108
|
attr_reader :self_type
|
109
|
+
attr_reader :break_context
|
110
|
+
attr_reader :type_env
|
69
111
|
|
70
|
-
def initialize(
|
71
|
-
@
|
112
|
+
def initialize(checker:, source:, annotations:, type_env:, typing:, self_type:, method_context:, block_context:, module_context:, break_context:)
|
113
|
+
@checker = checker
|
72
114
|
@source = source
|
73
115
|
@annotations = annotations
|
74
|
-
@var_types = var_types
|
75
|
-
@ivar_types = ivar_types
|
76
116
|
@typing = typing
|
77
117
|
@self_type = self_type
|
78
118
|
@block_context = block_context
|
79
119
|
@method_context = method_context
|
80
120
|
@module_context = module_context
|
121
|
+
@break_context = break_context
|
122
|
+
@type_env = type_env
|
81
123
|
end
|
82
124
|
|
83
|
-
def
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
125
|
+
def for_new_method(method_name, node, args:, self_type:)
|
126
|
+
annots = source.annotations(block: node)
|
127
|
+
type_env = TypeInference::TypeEnv.new(subtyping: checker,
|
128
|
+
const_env: module_context&.const_env || self.type_env.const_env)
|
129
|
+
|
130
|
+
self.type_env.const_types.each do |name, type|
|
131
|
+
type_env.set(const: name, type: type)
|
89
132
|
end
|
90
133
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
134
|
+
self_type = annots.self_type || self_type
|
135
|
+
|
136
|
+
self_interface = self_type && (self_type != Types.any || nil) && checker.resolve(self_type, with_initialize: true)
|
137
|
+
interface_method = self_interface&.yield_self {|interface| interface.methods[method_name] }
|
138
|
+
annotation_method = annotations.lookup_method_type(method_name)&.yield_self do |method_type|
|
139
|
+
Interface::Method.new(type_name: nil,
|
140
|
+
name: method_name,
|
141
|
+
types: [checker.builder.method_type_to_method_type(method_type,
|
142
|
+
current: current_namespace)],
|
143
|
+
super_method: interface_method&.super_method,
|
144
|
+
attributes: [])
|
95
145
|
end
|
96
|
-
end
|
97
146
|
|
98
|
-
|
99
|
-
|
147
|
+
if interface_method && annotation_method
|
148
|
+
result = checker.check_method(method_name,
|
149
|
+
annotation_method,
|
150
|
+
interface_method,
|
151
|
+
assumption: Set.new,
|
152
|
+
trace: Subtyping::Trace.new,
|
153
|
+
constraints: Subtyping::Constraints.empty)
|
154
|
+
|
155
|
+
if result.failure?
|
156
|
+
typing.add_error Errors::IncompatibleMethodTypeAnnotation.new(
|
157
|
+
node: node,
|
158
|
+
annotation_method: annotation_method,
|
159
|
+
interface_method: interface_method,
|
160
|
+
result: result
|
161
|
+
)
|
162
|
+
end
|
163
|
+
end
|
100
164
|
|
101
|
-
|
165
|
+
method = annotation_method || interface_method
|
102
166
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
unless TypeConstruction.valid_parameter_env?(var_types, args, method_type.params)
|
109
|
-
typing.add_error Errors::
|
167
|
+
case
|
168
|
+
when method && method.types.size == 1
|
169
|
+
method_type = method.types.first
|
170
|
+
return_type = method_type.return_type
|
171
|
+
var_types = TypeConstruction.parameter_types(args, method_type).transform_values {|type| absolute_type(type) }
|
172
|
+
unless TypeConstruction.valid_parameter_env?(var_types, args.reject {|arg| arg.type == :blockarg }, method_type.params)
|
173
|
+
typing.add_error Errors::MethodArityMismatch.new(node: node)
|
110
174
|
end
|
175
|
+
when method
|
176
|
+
typing.add_error Errors::MethodDefinitionWithOverloading.new(node: node, method: method)
|
177
|
+
return_type = union_type(*method.types.map(&:return_type))
|
178
|
+
var_types = {}
|
111
179
|
else
|
112
180
|
var_types = {}
|
113
181
|
end
|
114
182
|
|
115
|
-
|
116
|
-
|
183
|
+
if annots.return_type && return_type
|
184
|
+
return_type_relation = Subtyping::Relation.new(sub_type: annots.return_type,
|
185
|
+
super_type: return_type)
|
186
|
+
checker.check(return_type_relation, constraints: Subtyping::Constraints.empty).else do |result|
|
187
|
+
typing.add_error Errors::MethodReturnTypeAnnotationMismatch.new(node: node,
|
188
|
+
method_type: return_type,
|
189
|
+
annotation_type: annots.return_type,
|
190
|
+
result: result)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
constructor_method = method&.attributes&.include?(:constructor)
|
117
195
|
|
118
196
|
method_context = MethodContext.new(
|
119
197
|
name: method_name,
|
120
|
-
method:
|
121
|
-
method_type:
|
122
|
-
return_type: annots.return_type,
|
198
|
+
method: method,
|
199
|
+
method_type: method_type,
|
200
|
+
return_type: annots.return_type || return_type,
|
123
201
|
constructor: constructor_method
|
124
202
|
)
|
125
203
|
|
126
|
-
|
127
|
-
|
204
|
+
var_types.each do |name, type|
|
205
|
+
type_env.set(lvar: name, type: type)
|
128
206
|
end
|
129
207
|
|
208
|
+
ivar_types = {}
|
209
|
+
ivar_types.merge!(self_interface.ivars) if self_interface
|
210
|
+
ivar_types.merge!(annots.ivar_types)
|
211
|
+
|
212
|
+
ivar_types.each do |name, type|
|
213
|
+
type_env.set(ivar: name, type: type)
|
214
|
+
end
|
215
|
+
|
216
|
+
type_env = type_env.with_annotations(
|
217
|
+
lvar_types: annots.var_types.transform_values {|annot| absolute_type(annot.type) },
|
218
|
+
ivar_types: annots.ivar_types,
|
219
|
+
const_types: annots.const_types.transform_values {|type| absolute_type(type) }
|
220
|
+
)
|
221
|
+
|
130
222
|
self.class.new(
|
131
|
-
|
223
|
+
checker: checker,
|
132
224
|
source: source,
|
133
225
|
annotations: annots,
|
134
|
-
|
226
|
+
type_env: type_env,
|
135
227
|
block_context: nil,
|
136
228
|
self_type: self_type,
|
137
229
|
method_context: method_context,
|
138
230
|
typing: typing,
|
139
231
|
module_context: module_context,
|
140
|
-
|
232
|
+
break_context: nil
|
233
|
+
)
|
234
|
+
end
|
235
|
+
|
236
|
+
def for_module(node)
|
237
|
+
annots = source.annotations(block: node)
|
238
|
+
new_module_name = ModuleName.from_node(node.children.first) or raise "Unexpected module name: #{node.children.first}"
|
239
|
+
|
240
|
+
module_type = AST::Types::Name.new_instance(name: "::Module")
|
241
|
+
|
242
|
+
implement_module_name =
|
243
|
+
if annots.implement_module
|
244
|
+
annots.implement_module.name
|
245
|
+
else
|
246
|
+
absolute_name(new_module_name).yield_self do |module_name|
|
247
|
+
if checker.builder.signatures.module_name?(module_name)
|
248
|
+
signature = checker.builder.signatures.find_module(module_name)
|
249
|
+
AST::Annotation::Implements::Module.new(name: module_name,
|
250
|
+
args: signature.params&.variables || [])
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
if implement_module_name
|
256
|
+
module_name = implement_module_name.name
|
257
|
+
module_args = implement_module_name.args.map {|x| AST::Types::Var.new(name: x) }
|
258
|
+
|
259
|
+
abstract = checker.builder.build(TypeName::Instance.new(name: module_name))
|
260
|
+
|
261
|
+
instance_type = absolute_type(
|
262
|
+
AST::Types::Name.new_instance(name: module_name, args: module_args)
|
263
|
+
)
|
264
|
+
|
265
|
+
unless abstract.supers.empty?
|
266
|
+
instance_type = AST::Types::Intersection.build(
|
267
|
+
types: [instance_type, AST::Types::Name.new_instance(name: "::Object")] + abstract.supers.map {|x| absolute_type(x) }
|
268
|
+
)
|
269
|
+
end
|
270
|
+
|
271
|
+
module_type = AST::Types::Intersection.build(types: [
|
272
|
+
AST::Types::Name.new_instance(name: "::Module"),
|
273
|
+
absolute_type(AST::Types::Name.new_module(name: module_name, args: module_args))
|
274
|
+
])
|
275
|
+
end
|
276
|
+
|
277
|
+
if annots.instance_type
|
278
|
+
instance_type = absolute_type(annots.instance_type)
|
279
|
+
end
|
280
|
+
|
281
|
+
if annots.module_type
|
282
|
+
module_type = absolute_type(annots.module_type)
|
283
|
+
end
|
284
|
+
|
285
|
+
new_namespace = nested_namespace(new_module_name)
|
286
|
+
module_const_env = TypeInference::ConstantEnv.new(builder: checker.builder, current_namespace: new_namespace)
|
287
|
+
|
288
|
+
module_context_ = ModuleContext.new(
|
289
|
+
instance_type: instance_type,
|
290
|
+
module_type: module_type,
|
291
|
+
implement_name: implement_module_name,
|
292
|
+
current_namespace: new_namespace,
|
293
|
+
const_env: module_const_env
|
294
|
+
)
|
295
|
+
|
296
|
+
module_type_env = TypeInference::TypeEnv.build(annotations: annots,
|
297
|
+
subtyping: checker,
|
298
|
+
const_env: module_const_env,
|
299
|
+
signatures: checker.builder.signatures)
|
300
|
+
|
301
|
+
self.class.new(
|
302
|
+
checker: checker,
|
303
|
+
source: source,
|
304
|
+
annotations: annots,
|
305
|
+
type_env: module_type_env,
|
306
|
+
typing: typing,
|
307
|
+
method_context: nil,
|
308
|
+
block_context: nil,
|
309
|
+
module_context: module_context_,
|
310
|
+
self_type: module_context_.module_type,
|
311
|
+
break_context: nil
|
141
312
|
)
|
142
313
|
end
|
143
314
|
|
144
315
|
def for_class(node)
|
145
316
|
annots = source.annotations(block: node)
|
317
|
+
new_class_name = ModuleName.from_node(node.children.first) or raise "Unexpected class name: #{node.children.first}"
|
146
318
|
|
147
|
-
|
148
|
-
|
149
|
-
|
319
|
+
implement_module_name =
|
320
|
+
if annots.implement_module
|
321
|
+
annots.implement_module.name
|
322
|
+
else
|
323
|
+
absolute_name(new_class_name).yield_self do |name|
|
324
|
+
if checker.builder.signatures.class_name?(name)
|
325
|
+
signature = checker.builder.signatures.find_class(name)
|
326
|
+
AST::Annotation::Implements::Module.new(name: name,
|
327
|
+
args: signature.params&.variables || [])
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
150
331
|
|
151
|
-
|
152
|
-
|
332
|
+
if implement_module_name
|
333
|
+
class_name = implement_module_name.name
|
334
|
+
class_args = implement_module_name.args.map {|x| AST::Types::Var.new(name: x) }
|
335
|
+
|
336
|
+
_ = checker.builder.build(TypeName::Instance.new(name: class_name))
|
337
|
+
|
338
|
+
instance_type = AST::Types::Name.new_instance(name: class_name, args: class_args)
|
339
|
+
module_type = AST::Types::Name.new_class(name: class_name, args: [], constructor: nil)
|
153
340
|
end
|
154
341
|
|
342
|
+
new_namespace = nested_namespace(new_class_name)
|
343
|
+
class_const_env = TypeInference::ConstantEnv.new(builder: checker.builder, current_namespace: new_namespace)
|
344
|
+
|
155
345
|
module_context = ModuleContext.new(
|
156
346
|
instance_type: annots.instance_type || instance_type,
|
157
347
|
module_type: annots.module_type || module_type,
|
158
|
-
|
348
|
+
implement_name: implement_module_name,
|
349
|
+
current_namespace: new_namespace,
|
350
|
+
const_env: class_const_env
|
351
|
+
)
|
352
|
+
|
353
|
+
class_type_env = TypeInference::TypeEnv.build(
|
354
|
+
annotations: annots,
|
355
|
+
const_env: class_const_env,
|
356
|
+
signatures: checker.builder.signatures,
|
357
|
+
subtyping: checker
|
159
358
|
)
|
160
359
|
|
161
360
|
self.class.new(
|
162
|
-
|
361
|
+
checker: checker,
|
163
362
|
source: source,
|
164
363
|
annotations: annots,
|
165
|
-
|
364
|
+
type_env: class_type_env,
|
166
365
|
typing: typing,
|
167
366
|
method_context: nil,
|
168
367
|
block_context: nil,
|
169
368
|
module_context: module_context,
|
170
|
-
self_type: module_context.module_type
|
369
|
+
self_type: module_context.module_type,
|
370
|
+
break_context: nil
|
171
371
|
)
|
172
372
|
end
|
173
373
|
|
174
|
-
def
|
175
|
-
|
176
|
-
when :begin
|
177
|
-
type = each_child_node(node).map do |child|
|
178
|
-
synthesize(child)
|
179
|
-
end.last
|
374
|
+
def for_branch(node, truthy_vars: Set.new, type_case_override: nil)
|
375
|
+
annots = source.annotations(block: node)
|
180
376
|
|
181
|
-
|
377
|
+
type_env = self.type_env
|
182
378
|
|
183
|
-
|
184
|
-
|
185
|
-
|
379
|
+
lvar_types = self.type_env.lvar_types.each.with_object({}) do |(var, type), env|
|
380
|
+
if truthy_vars.member?(var)
|
381
|
+
env[var] = TypeConstruction.unwrap(type)
|
382
|
+
else
|
383
|
+
env[var] = type
|
384
|
+
end
|
385
|
+
end
|
386
|
+
type_env = type_env.with_annotations(lvar_types: lvar_types) do |var, relation, result|
|
387
|
+
raise "Unexpected annotate failure: #{relation}"
|
388
|
+
end
|
186
389
|
|
187
|
-
|
390
|
+
if type_case_override
|
391
|
+
type_env = type_env.with_annotations(lvar_types: type_case_override) do |var, relation, result|
|
392
|
+
typing.add_error(
|
393
|
+
Errors::IncompatibleTypeCase.new(node: node,
|
394
|
+
var_name: var,
|
395
|
+
relation: relation,
|
396
|
+
result: result)
|
397
|
+
)
|
398
|
+
end
|
399
|
+
end
|
188
400
|
|
189
|
-
|
190
|
-
|
401
|
+
type_env = type_env.with_annotations(
|
402
|
+
lvar_types: annots.var_types.transform_values {|a| absolute_type(a.type) },
|
403
|
+
ivar_types: annots.ivar_types.transform_values {|ty| absolute_type(ty) },
|
404
|
+
const_types: annots.const_types.transform_values {|ty| absolute_type(ty) },
|
405
|
+
gvar_types: {}
|
406
|
+
) do |var, relation, result|
|
407
|
+
typing.add_error(
|
408
|
+
Errors::IncompatibleAnnotation.new(node: node,
|
409
|
+
var_name: var,
|
410
|
+
relation: relation,
|
411
|
+
result: result)
|
412
|
+
)
|
413
|
+
end
|
191
414
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
415
|
+
with(type_env: type_env)
|
416
|
+
end
|
417
|
+
|
418
|
+
NOTHING = ::Object.new
|
419
|
+
|
420
|
+
def with(annotations: NOTHING, type_env: NOTHING, method_context: NOTHING, block_context: NOTHING, module_context: NOTHING, self_type: NOTHING, break_context: NOTHING)
|
421
|
+
self.class.new(
|
422
|
+
checker: checker,
|
423
|
+
source: source,
|
424
|
+
annotations: annotations.equal?(NOTHING) ? self.annotations : annotations,
|
425
|
+
type_env: type_env.equal?(NOTHING) ? self.type_env : type_env,
|
426
|
+
typing: typing,
|
427
|
+
method_context: method_context.equal?(NOTHING) ? self.method_context : method_context,
|
428
|
+
block_context: block_context.equal?(NOTHING) ? self.block_context : block_context,
|
429
|
+
module_context: module_context.equal?(NOTHING) ? self.module_context : module_context,
|
430
|
+
self_type: self_type.equal?(NOTHING) ? self.self_type : self_type,
|
431
|
+
break_context: break_context.equal?(NOTHING) ? self.break_context : break_context
|
432
|
+
)
|
433
|
+
end
|
198
434
|
|
199
|
-
|
200
|
-
|
201
|
-
|
435
|
+
def synthesize(node)
|
436
|
+
Steep.logger.tagged "synthesize:(#{node.location.expression.to_s.split(/:/, 2).last})" do
|
437
|
+
Steep.logger.debug node.type
|
438
|
+
case node.type
|
439
|
+
when :begin, :kwbegin
|
440
|
+
yield_self do
|
441
|
+
type = each_child_node(node).map do |child|
|
442
|
+
synthesize(child)
|
443
|
+
end.last
|
202
444
|
|
203
|
-
|
204
|
-
check(value, type) do |_, value_type|
|
205
|
-
typing.add_error(Errors::IncompatibleAssignment.new(node: node, lhs_type: type, rhs_type: value_type))
|
445
|
+
typing.add_typing(node, type)
|
206
446
|
end
|
207
|
-
typing.add_typing(node, type)
|
208
|
-
else
|
209
|
-
value_type = synthesize(value)
|
210
|
-
typing.add_typing(node, value_type)
|
211
|
-
end
|
212
447
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
else
|
218
|
-
fallback_to_any node
|
219
|
-
end
|
448
|
+
when :lvasgn
|
449
|
+
yield_self do
|
450
|
+
var = node.children[0]
|
451
|
+
rhs = node.children[1]
|
220
452
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
else
|
228
|
-
module_type
|
229
|
-
end
|
230
|
-
typing.add_typing(node, type)
|
231
|
-
else
|
232
|
-
type_send(node, with_block: false)
|
233
|
-
end
|
453
|
+
if var.name == :_
|
454
|
+
typing.add_typing(node, Types.any)
|
455
|
+
else
|
456
|
+
type_assignment(var, rhs, node)
|
457
|
+
end
|
458
|
+
end
|
234
459
|
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
with_block: false)
|
244
|
-
else
|
245
|
-
typing.add_error(Errors::UnexpectedSuper.new(node: node, method: method_context.name))
|
460
|
+
when :lvar
|
461
|
+
yield_self do
|
462
|
+
var = node.children[0]
|
463
|
+
type = type_env.get(lvar: var.name) do
|
464
|
+
fallback_to_any node
|
465
|
+
end
|
466
|
+
|
467
|
+
typing.add_typing node, type
|
246
468
|
end
|
247
|
-
end
|
248
469
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
fallback_to_any node
|
253
|
-
end
|
470
|
+
when :ivasgn
|
471
|
+
name = node.children[0]
|
472
|
+
value = node.children[1]
|
254
473
|
|
255
|
-
|
256
|
-
send_node, params, block = node.children
|
474
|
+
type_ivasgn(name, value, node)
|
257
475
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
var_types_[var] = type
|
264
|
-
typing.add_var_type(var, type)
|
476
|
+
when :ivar
|
477
|
+
yield_self do
|
478
|
+
name = node.children[0]
|
479
|
+
type = type_env.get(ivar: name) do
|
480
|
+
fallback_to_any node
|
265
481
|
end
|
482
|
+
typing.add_typing(node, type)
|
483
|
+
end
|
266
484
|
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
)
|
485
|
+
when :send
|
486
|
+
yield_self do
|
487
|
+
if self_class?(node)
|
488
|
+
module_type = module_context.module_type
|
489
|
+
type = if module_type.is_a?(AST::Types::Name) && module_type.name.is_a?(TypeName::Class)
|
490
|
+
AST::Types::Name.new(name: module_type.name.updated(constructor: method_context.constructor),
|
491
|
+
args: module_type.args)
|
492
|
+
else
|
493
|
+
module_type
|
494
|
+
end
|
495
|
+
typing.add_typing(node, type)
|
496
|
+
else
|
497
|
+
type_send(node, send_node: node, block_params: nil, block_body: nil)
|
498
|
+
end
|
499
|
+
end
|
283
500
|
|
284
|
-
|
285
|
-
|
501
|
+
when :csend
|
502
|
+
yield_self do
|
503
|
+
type = if self_class?(node)
|
504
|
+
module_type = module_context.module_type
|
505
|
+
type = if module_type.is_a?(AST::Types::Name)
|
506
|
+
AST::Types::Name.new(name: module_type.name.updated(constructor: method_context.constructor),
|
507
|
+
args: module_type.args)
|
508
|
+
else
|
509
|
+
module_type
|
510
|
+
end
|
511
|
+
typing.add_typing(node, type)
|
512
|
+
else
|
513
|
+
type_send(node, send_node: node, block_params: nil, block_body: nil, unwrap: true)
|
514
|
+
end
|
515
|
+
|
516
|
+
union_type(type, Types.nil_instance)
|
517
|
+
end
|
518
|
+
|
519
|
+
when :match_with_lvasgn
|
520
|
+
each_child_node(node) do |child|
|
521
|
+
synthesize(child)
|
522
|
+
end
|
523
|
+
typing.add_typing(node, Types.any)
|
524
|
+
|
525
|
+
when :op_asgn
|
526
|
+
yield_self do
|
527
|
+
lhs, op, rhs = node.children
|
528
|
+
|
529
|
+
synthesize(rhs)
|
530
|
+
|
531
|
+
lhs_type = case lhs.type
|
532
|
+
when :lvasgn
|
533
|
+
type_env.get(lvar: lhs.children.first.name) do
|
534
|
+
break
|
535
|
+
end
|
536
|
+
when :ivasgn
|
537
|
+
type_env.get(ivar: lhs.children.first) do
|
538
|
+
break
|
539
|
+
end
|
540
|
+
else
|
541
|
+
Steep.logger.error("Unexpected op_asgn lhs: #{lhs.type}")
|
542
|
+
nil
|
543
|
+
end
|
544
|
+
|
545
|
+
case
|
546
|
+
when lhs_type == Types.any
|
547
|
+
typing.add_typing(node, lhs_type)
|
548
|
+
when !lhs_type
|
549
|
+
fallback_to_any(node)
|
550
|
+
else
|
551
|
+
lhs_interface = checker.resolve(lhs_type, with_initialize: false)
|
552
|
+
op_method = lhs_interface.methods[op]
|
553
|
+
|
554
|
+
if op_method
|
555
|
+
args = TypeInference::SendArgs.from_nodes([rhs])
|
556
|
+
return_type_or_error = type_method_call(node,
|
557
|
+
receiver_type: lhs_type,
|
558
|
+
method: op_method,
|
559
|
+
args: args,
|
560
|
+
block_params: nil,
|
561
|
+
block_body: nil)
|
562
|
+
|
563
|
+
if return_type_or_error.is_a?(Errors::Base)
|
564
|
+
typing.add_error return_type_or_error
|
565
|
+
else
|
566
|
+
result = checker.check(
|
567
|
+
Subtyping::Relation.new(sub_type: return_type_or_error, super_type: lhs_type),
|
568
|
+
constraints: Subtyping::Constraints.empty
|
569
|
+
)
|
570
|
+
if result.failure?
|
571
|
+
typing.add_error(
|
572
|
+
Errors::IncompatibleAssignment.new(
|
573
|
+
node: node,
|
574
|
+
lhs_type: lhs_type,
|
575
|
+
rhs_type: return_type_or_error,
|
576
|
+
result: result
|
577
|
+
)
|
578
|
+
)
|
579
|
+
end
|
580
|
+
end
|
581
|
+
else
|
582
|
+
typing.add_error Errors::NoMethod.new(node: node, method: op, type: lhs_type)
|
583
|
+
end
|
584
|
+
|
585
|
+
typing.add_typing(node, lhs_type)
|
286
586
|
end
|
587
|
+
end
|
287
588
|
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
589
|
+
when :super
|
590
|
+
yield_self do
|
591
|
+
if self_type && method_context&.method
|
592
|
+
if method_context.super_method
|
593
|
+
each_child_node(node) do |child| synthesize(child) end
|
594
|
+
|
595
|
+
super_method = method_context.super_method
|
596
|
+
args = TypeInference::SendArgs.from_nodes(node.children.dup)
|
597
|
+
|
598
|
+
return_type_or_error = type_method_call(node,
|
599
|
+
receiver_type: self_type,
|
600
|
+
method: super_method,
|
601
|
+
args: args,
|
602
|
+
block_params: nil,
|
603
|
+
block_body: nil)
|
604
|
+
|
605
|
+
if return_type_or_error.is_a?(Errors::Base)
|
606
|
+
fallback_to_any node do
|
607
|
+
return_type_or_error
|
608
|
+
end
|
609
|
+
else
|
610
|
+
typing.add_typing node, return_type_or_error
|
611
|
+
end
|
612
|
+
else
|
613
|
+
fallback_to_any node do
|
614
|
+
Errors::UnexpectedSuper.new(node: node, method: method_context.name)
|
615
|
+
end
|
616
|
+
end
|
293
617
|
else
|
294
|
-
|
295
|
-
|
296
|
-
|
618
|
+
typing.add_typing node, Types.any
|
619
|
+
end
|
620
|
+
end
|
621
|
+
|
622
|
+
when :block
|
623
|
+
yield_self do
|
624
|
+
send_node, params, body = node.children
|
625
|
+
type_send(node, send_node: send_node, block_params: params, block_body: body)
|
626
|
+
end
|
627
|
+
|
628
|
+
when :def
|
629
|
+
new = for_new_method(node.children[0],
|
630
|
+
node,
|
631
|
+
args: node.children[1].children,
|
632
|
+
self_type: module_context&.instance_type)
|
633
|
+
|
634
|
+
each_child_node(node.children[1]) do |arg|
|
635
|
+
new.synthesize(arg)
|
636
|
+
end
|
637
|
+
|
638
|
+
if node.children[2]
|
639
|
+
return_type = new.method_context&.return_type
|
640
|
+
if return_type && !return_type.is_a?(AST::Types::Void)
|
641
|
+
new.check(node.children[2], return_type) do |_, actual_type, result|
|
642
|
+
typing.add_error(Errors::MethodBodyTypeMismatch.new(node: node,
|
643
|
+
expected: return_type,
|
644
|
+
actual: actual_type,
|
645
|
+
result: result))
|
646
|
+
end
|
647
|
+
else
|
648
|
+
new.synthesize(node.children[2])
|
649
|
+
end
|
650
|
+
end
|
651
|
+
|
652
|
+
if module_context
|
653
|
+
module_context.defined_instance_methods << node.children[0]
|
654
|
+
end
|
655
|
+
|
656
|
+
typing.add_typing(node, Types.any)
|
657
|
+
|
658
|
+
when :defs
|
659
|
+
synthesize(node.children[0]).tap do |self_type|
|
660
|
+
new = for_new_method(node.children[1],
|
661
|
+
node,
|
662
|
+
args: node.children[2].children,
|
663
|
+
self_type: self_type)
|
664
|
+
|
665
|
+
each_child_node(node.children[2]) do |arg|
|
666
|
+
new.synthesize(arg)
|
667
|
+
end
|
668
|
+
|
669
|
+
if node.children[3]
|
670
|
+
return_type = new.method_context&.return_type
|
671
|
+
if return_type && !return_type.is_a?(AST::Types::Void)
|
672
|
+
new.check(node.children[3], return_type) do |return_type, actual_type, result|
|
673
|
+
typing.add_error(Errors::MethodBodyTypeMismatch.new(node: node,
|
674
|
+
expected: return_type,
|
675
|
+
actual: actual_type,
|
676
|
+
result: result))
|
297
677
|
end
|
678
|
+
else
|
679
|
+
new.synthesize(node.children[3])
|
298
680
|
end
|
681
|
+
end
|
682
|
+
end
|
299
683
|
|
300
|
-
|
684
|
+
if module_context
|
685
|
+
if node.children[0].type == :self
|
686
|
+
module_context.defined_module_methods << node.children[1]
|
301
687
|
end
|
688
|
+
end
|
689
|
+
|
690
|
+
typing.add_typing(node, Types.symbol_instance)
|
691
|
+
|
692
|
+
when :return
|
693
|
+
yield_self do
|
694
|
+
if node.children.size > 0
|
695
|
+
return_types = node.children.map do |value|
|
696
|
+
synthesize(value)
|
697
|
+
end
|
302
698
|
|
699
|
+
value_type = if return_types.size == 1
|
700
|
+
return_types.first
|
701
|
+
else
|
702
|
+
Types.array_instance(union_type(*return_types))
|
703
|
+
end
|
704
|
+
|
705
|
+
if method_context&.return_type && !method_context.return_type.is_a?(AST::Types::Void)
|
706
|
+
result = checker.check(
|
707
|
+
Subtyping::Relation.new(sub_type: value_type,
|
708
|
+
super_type: method_context.return_type),
|
709
|
+
constraints: Subtyping::Constraints.empty
|
710
|
+
)
|
711
|
+
|
712
|
+
if result.failure?
|
713
|
+
typing.add_error(Errors::ReturnTypeMismatch.new(node: node,
|
714
|
+
expected: method_context.return_type,
|
715
|
+
actual: value_type,
|
716
|
+
result: result))
|
717
|
+
end
|
718
|
+
end
|
719
|
+
end
|
720
|
+
|
721
|
+
typing.add_typing(node, Types.any)
|
722
|
+
end
|
723
|
+
|
724
|
+
when :break
|
725
|
+
value = node.children[0]
|
726
|
+
|
727
|
+
if break_context
|
728
|
+
case
|
729
|
+
when value && break_context.break_type
|
730
|
+
check(value, break_context.break_type) do |break_type, actual_type, result|
|
731
|
+
typing.add_error Errors::BreakTypeMismatch.new(node: node,
|
732
|
+
expected: break_type,
|
733
|
+
actual: actual_type,
|
734
|
+
result: result)
|
735
|
+
end
|
736
|
+
when !value
|
737
|
+
# ok
|
738
|
+
else
|
739
|
+
synthesize(value) if value
|
740
|
+
typing.add_error Errors::UnexpectedJumpValue.new(node: node)
|
741
|
+
end
|
303
742
|
else
|
304
|
-
|
305
|
-
|
743
|
+
synthesize(value)
|
744
|
+
typing.add_error Errors::UnexpectedJump.new(node: node)
|
306
745
|
end
|
307
|
-
end
|
308
746
|
|
309
|
-
|
747
|
+
typing.add_typing(node, Types.any)
|
310
748
|
|
311
|
-
|
312
|
-
|
313
|
-
node,
|
314
|
-
args: node.children[1].children,
|
315
|
-
self_type: module_context&.instance_type)
|
749
|
+
when :next
|
750
|
+
value = node.children[0]
|
316
751
|
|
317
|
-
|
318
|
-
|
319
|
-
|
752
|
+
if break_context
|
753
|
+
case
|
754
|
+
when value && break_context.next_type
|
755
|
+
check(value, break_context.next_type) do |break_type, actual_type, result|
|
756
|
+
typing.add_error Errors::BreakTypeMismatch.new(node: node,
|
757
|
+
expected: break_type,
|
758
|
+
actual: actual_type,
|
759
|
+
result: result)
|
760
|
+
end
|
761
|
+
when !value
|
762
|
+
# ok
|
763
|
+
else
|
764
|
+
synthesize(value) if value
|
765
|
+
typing.add_error Errors::UnexpectedJumpValue.new(node: node)
|
766
|
+
end
|
767
|
+
else
|
768
|
+
synthesize(value)
|
769
|
+
typing.add_error Errors::UnexpectedJump.new(node: node)
|
770
|
+
end
|
320
771
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
772
|
+
typing.add_typing(node, Types.any)
|
773
|
+
|
774
|
+
when :retry
|
775
|
+
unless break_context
|
776
|
+
typing.add_error Errors::UnexpectedJump.new(node: node)
|
777
|
+
end
|
778
|
+
typing.add_typing(node, Types.any)
|
779
|
+
|
780
|
+
when :arg, :kwarg, :procarg0
|
781
|
+
yield_self do
|
782
|
+
var = node.children[0]
|
783
|
+
type = type_env.get(lvar: var.name) do
|
784
|
+
fallback_to_any node
|
328
785
|
end
|
786
|
+
typing.add_typing(node, type)
|
787
|
+
end
|
788
|
+
|
789
|
+
when :optarg, :kwoptarg
|
790
|
+
yield_self do
|
791
|
+
var = node.children[0]
|
792
|
+
rhs = node.children[1]
|
793
|
+
type_assignment(var, rhs, node)
|
794
|
+
end
|
795
|
+
|
796
|
+
when :restarg
|
797
|
+
yield_self do
|
798
|
+
var = node.children[0]
|
799
|
+
type = type_env.get(lvar: var.name) do
|
800
|
+
typing.add_error Errors::FallbackAny.new(node: node)
|
801
|
+
Types.array_instance(Types.any)
|
802
|
+
end
|
803
|
+
|
804
|
+
typing.add_typing(node, type)
|
805
|
+
end
|
806
|
+
|
807
|
+
when :kwrestarg
|
808
|
+
yield_self do
|
809
|
+
var = node.children[0]
|
810
|
+
type = type_env.get(lvar: var.name) do
|
811
|
+
typing.add_error Errors::FallbackAny.new(node: node)
|
812
|
+
Types.hash_instance(Types.symbol_instance, Types.any)
|
813
|
+
end
|
814
|
+
|
815
|
+
typing.add_typing(node, type)
|
816
|
+
end
|
817
|
+
|
818
|
+
when :int
|
819
|
+
typing.add_typing(node, AST::Types::Name.new_instance(name: "::Integer"))
|
820
|
+
|
821
|
+
when :float
|
822
|
+
typing.add_typing(node, AST::Types::Name.new_instance(name: "::Float"))
|
823
|
+
|
824
|
+
when :nil
|
825
|
+
typing.add_typing(node, Types.nil_instance)
|
826
|
+
|
827
|
+
when :sym
|
828
|
+
typing.add_typing(node, Types.symbol_instance)
|
829
|
+
|
830
|
+
when :str
|
831
|
+
typing.add_typing(node, Types.string_instance)
|
832
|
+
|
833
|
+
when :true, :false
|
834
|
+
typing.add_typing(node, AST::Types::Name.new_interface(name: :_Boolean))
|
835
|
+
|
836
|
+
when :hash
|
837
|
+
yield_self do
|
838
|
+
key_types = []
|
839
|
+
value_types = []
|
840
|
+
|
841
|
+
each_child_node(node) do |child|
|
842
|
+
case child.type
|
843
|
+
when :pair
|
844
|
+
key, value = child.children
|
845
|
+
key_types << synthesize(key)
|
846
|
+
value_types << synthesize(value)
|
847
|
+
when :kwsplat
|
848
|
+
splat_type = synthesize(child.children[0])
|
849
|
+
|
850
|
+
if splat_type.is_a?(AST::Types::Name) && splat_type.name == TypeName::Instance.new(name: ModuleName.parse("::Hash"))
|
851
|
+
key_types << splat_type.args[0]
|
852
|
+
value_types << splat_type.args[1]
|
853
|
+
else
|
854
|
+
typing.add_error Errors::UnexpectedSplat.new(node: child, type: splat_type)
|
855
|
+
key_types << Types.any
|
856
|
+
value_types << Types.any
|
857
|
+
end
|
858
|
+
else
|
859
|
+
raise "Unexpected non pair: #{child.inspect}" unless child.type == :pair
|
860
|
+
end
|
861
|
+
end
|
862
|
+
|
863
|
+
key_type = key_types.empty? ? Types.any : AST::Types::Union.build(types: key_types)
|
864
|
+
value_type = value_types.empty? ? Types.any : AST::Types::Union.build(types: value_types)
|
865
|
+
|
866
|
+
typing.add_typing(node, Types.hash_instance(key_type, value_type))
|
867
|
+
end
|
868
|
+
|
869
|
+
when :dstr
|
870
|
+
each_child_node(node) do |child|
|
871
|
+
synthesize(child)
|
872
|
+
end
|
873
|
+
|
874
|
+
typing.add_typing(node, Types.string_instance)
|
875
|
+
|
876
|
+
when :dsym
|
877
|
+
each_child_node(node) do |child|
|
878
|
+
synthesize(child)
|
879
|
+
end
|
880
|
+
|
881
|
+
typing.add_typing(node, Types.symbol_instance)
|
882
|
+
|
883
|
+
when :class
|
884
|
+
yield_self do
|
885
|
+
for_class(node).tap do |constructor|
|
886
|
+
constructor.synthesize(node.children[2]) if node.children[2]
|
887
|
+
|
888
|
+
if constructor.module_context&.implement_name && !namespace_module?(node)
|
889
|
+
constructor.validate_method_definitions(node, constructor.module_context.implement_name)
|
890
|
+
end
|
891
|
+
end
|
892
|
+
|
893
|
+
typing.add_typing(node, Types.nil_instance)
|
894
|
+
end
|
895
|
+
|
896
|
+
when :module
|
897
|
+
yield_self do
|
898
|
+
for_module(node).yield_self do |constructor|
|
899
|
+
constructor.synthesize(node.children[1]) if node.children[1]
|
900
|
+
|
901
|
+
if constructor.module_context&.implement_name && !namespace_module?(node)
|
902
|
+
constructor.validate_method_definitions(node, constructor.module_context.implement_name)
|
903
|
+
end
|
904
|
+
end
|
905
|
+
|
906
|
+
typing.add_typing(node, Types.nil_instance)
|
907
|
+
end
|
908
|
+
|
909
|
+
when :self
|
910
|
+
if self_type
|
911
|
+
typing.add_typing(node, self_type)
|
329
912
|
else
|
330
|
-
|
913
|
+
fallback_to_any node
|
331
914
|
end
|
332
|
-
end
|
333
915
|
|
334
|
-
|
335
|
-
|
336
|
-
|
916
|
+
when :const
|
917
|
+
const_name = ModuleName.from_node(node)
|
918
|
+
if const_name
|
919
|
+
type = type_env.get(const: const_name) do
|
920
|
+
fallback_to_any node
|
921
|
+
end
|
922
|
+
typing.add_typing node, type
|
923
|
+
else
|
924
|
+
fallback_to_any node
|
925
|
+
end
|
337
926
|
|
338
|
-
|
927
|
+
when :casgn
|
928
|
+
yield_self do
|
929
|
+
const_name = ModuleName.from_node(node)
|
930
|
+
if const_name
|
931
|
+
value_type = synthesize(node.children.last)
|
932
|
+
type = type_env.assign(const: const_name, type: value_type) do |error|
|
933
|
+
case error
|
934
|
+
when Subtyping::Result::Failure
|
935
|
+
const_type = type_env.get(const: const_name)
|
936
|
+
typing.add_error(Errors::IncompatibleAssignment.new(node: node,
|
937
|
+
lhs_type: const_type,
|
938
|
+
rhs_type: value_type,
|
939
|
+
result: error))
|
940
|
+
when nil
|
941
|
+
typing.add_error(Errors::UnknownConstantAssigned.new(node: node, type: value_type))
|
942
|
+
end
|
943
|
+
end
|
339
944
|
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
945
|
+
typing.add_typing(node, type)
|
946
|
+
else
|
947
|
+
synthesize(node.children.last)
|
948
|
+
fallback_to_any(node)
|
949
|
+
end
|
950
|
+
end
|
346
951
|
|
347
|
-
|
348
|
-
|
952
|
+
when :yield
|
953
|
+
if method_context&.method_type
|
954
|
+
if method_context.block_type
|
955
|
+
block_type = method_context.block_type
|
956
|
+
block_type.params.flat_unnamed_params.map(&:last).zip(node.children).each do |(type, node)|
|
957
|
+
if node && type
|
958
|
+
check(node, type) do |_, rhs_type, result|
|
959
|
+
typing.add_error(Errors::IncompatibleAssignment.new(node: node,
|
960
|
+
lhs_type: type,
|
961
|
+
rhs_type: rhs_type,
|
962
|
+
result: result))
|
963
|
+
end
|
964
|
+
end
|
965
|
+
end
|
966
|
+
|
967
|
+
typing.add_typing(node, block_type.return_type)
|
968
|
+
else
|
969
|
+
typing.add_error(Errors::UnexpectedYield.new(node: node))
|
970
|
+
fallback_to_any node
|
971
|
+
end
|
972
|
+
else
|
973
|
+
fallback_to_any node
|
349
974
|
end
|
350
975
|
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
976
|
+
when :zsuper
|
977
|
+
yield_self do
|
978
|
+
if method_context&.method
|
979
|
+
if method_context.super_method
|
980
|
+
types = method_context.super_method.types.map(&:return_type)
|
981
|
+
typing.add_typing(node, union_type(*types))
|
982
|
+
else
|
983
|
+
typing.add_error(Errors::UnexpectedSuper.new(node: node, method: method_context.name))
|
984
|
+
fallback_to_any node
|
985
|
+
end
|
986
|
+
else
|
987
|
+
fallback_to_any node
|
988
|
+
end
|
989
|
+
end
|
990
|
+
|
991
|
+
when :array
|
992
|
+
yield_self do
|
993
|
+
if node.children.empty?
|
994
|
+
typing.add_typing(node, Types.array_instance(Types.any))
|
995
|
+
else
|
996
|
+
types = node.children.flat_map do |e|
|
997
|
+
if e.type == :splat
|
998
|
+
Steep.logger.info "Typing of splat in array is incompatible with Ruby; it does not use #to_a method"
|
999
|
+
synthesize(e.children.first).yield_self do |type|
|
1000
|
+
case type
|
1001
|
+
when AST::Types::Union
|
1002
|
+
type.types
|
1003
|
+
else
|
1004
|
+
[type]
|
1005
|
+
end
|
1006
|
+
end.map do |type|
|
1007
|
+
case
|
1008
|
+
when type.is_a?(AST::Types::Name) && type.name.is_a?(TypeName::Instance) && type.name.name == ModuleName.new(name: "Array", absolute: true)
|
1009
|
+
type.args.first
|
1010
|
+
when type.is_a?(AST::Types::Name) && type.name.is_a?(TypeName::Instance) && type.name.name == ModuleName.new(name: "Range", absolute: true)
|
1011
|
+
type.args.first
|
1012
|
+
else
|
1013
|
+
type
|
1014
|
+
end
|
1015
|
+
end
|
1016
|
+
else
|
1017
|
+
[synthesize(e)]
|
1018
|
+
end
|
357
1019
|
end
|
358
|
-
|
359
|
-
|
1020
|
+
|
1021
|
+
typing.add_typing(node, Types.array_instance(AST::Types::Union.build(types: types)))
|
360
1022
|
end
|
361
1023
|
end
|
362
|
-
end
|
363
1024
|
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
end
|
1025
|
+
when :and
|
1026
|
+
yield_self do
|
1027
|
+
left, right = node.children
|
1028
|
+
left_type = synthesize(left)
|
369
1029
|
|
370
|
-
|
1030
|
+
truthy_vars = TypeConstruction.truthy_variables(left)
|
1031
|
+
right_type, right_env = for_branch(right, truthy_vars: truthy_vars).yield_self do |constructor|
|
1032
|
+
type = constructor.synthesize(right)
|
1033
|
+
[type, constructor.type_env]
|
1034
|
+
end
|
371
1035
|
|
372
|
-
|
373
|
-
|
1036
|
+
type_env.join!([right_env, TypeInference::TypeEnv.new(subtyping: checker,
|
1037
|
+
const_env: nil)])
|
374
1038
|
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
typing.
|
379
|
-
expected: method_context.return_type,
|
380
|
-
actual: actual_type))
|
1039
|
+
if Types.boolean?(left_type)
|
1040
|
+
typing.add_typing(node, union_type(left_type, right_type))
|
1041
|
+
else
|
1042
|
+
typing.add_typing(node, union_type(right_type, Types.nil_instance))
|
381
1043
|
end
|
382
|
-
else
|
383
|
-
synthesize(value)
|
384
1044
|
end
|
385
|
-
end
|
386
1045
|
|
387
|
-
|
1046
|
+
when :or
|
1047
|
+
types = each_child_node(node).map {|child| synthesize(child) }
|
1048
|
+
type = union_type(*types)
|
1049
|
+
typing.add_typing(node, type)
|
1050
|
+
|
1051
|
+
when :if
|
1052
|
+
cond, true_clause, false_clause = node.children
|
1053
|
+
synthesize cond
|
388
1054
|
|
389
|
-
|
390
|
-
value = node.children[0]
|
1055
|
+
truthy_vars = TypeConstruction.truthy_variables(cond)
|
391
1056
|
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
1057
|
+
if true_clause
|
1058
|
+
true_type, true_env = for_branch(true_clause, truthy_vars: truthy_vars).yield_self do |constructor|
|
1059
|
+
type = constructor.synthesize(true_clause)
|
1060
|
+
[type, constructor.type_env]
|
1061
|
+
end
|
1062
|
+
end
|
1063
|
+
if false_clause
|
1064
|
+
false_type, false_env = for_branch(false_clause).yield_self do |constructor|
|
1065
|
+
type = constructor.synthesize(false_clause)
|
1066
|
+
[type, constructor.type_env]
|
398
1067
|
end
|
399
|
-
else
|
400
|
-
synthesize(value)
|
401
1068
|
end
|
402
|
-
end
|
403
|
-
|
404
|
-
typing.add_typing(node, Types::Any.new)
|
405
1069
|
|
406
|
-
|
407
|
-
|
408
|
-
if (type = variable_type(var))
|
409
|
-
typing.add_var_type(var, type)
|
410
|
-
else
|
411
|
-
fallback_to_any node
|
412
|
-
end
|
1070
|
+
type_env.join!([true_env, false_env].compact)
|
1071
|
+
typing.add_typing(node, union_type(true_type, false_type))
|
413
1072
|
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
type_assignment(var, rhs, node)
|
1073
|
+
when :case
|
1074
|
+
yield_self do
|
1075
|
+
cond, *whens = node.children
|
418
1076
|
|
419
|
-
|
420
|
-
|
1077
|
+
if cond
|
1078
|
+
cond_type = synthesize(cond)
|
1079
|
+
if cond_type.is_a?(AST::Types::Union)
|
1080
|
+
var_names = TypeConstruction.value_variables(cond)
|
1081
|
+
var_types = cond_type.types.dup
|
1082
|
+
end
|
1083
|
+
end
|
421
1084
|
|
422
|
-
|
423
|
-
|
1085
|
+
pairs = whens.each.with_object([]) do |clause, pairs|
|
1086
|
+
if clause&.type == :when
|
1087
|
+
test_types = clause.children.take(clause.children.size - 1).map do |child|
|
1088
|
+
synthesize(child)
|
1089
|
+
end
|
424
1090
|
|
425
|
-
|
426
|
-
|
1091
|
+
if (body = clause.children.last)
|
1092
|
+
if var_names && var_types && test_types.all? {|type| type.is_a?(AST::Types::Name) && type.name.is_a?(TypeName::Class) && type.args.empty? }
|
1093
|
+
var_types_in_body = test_types.flat_map {|test_type|
|
1094
|
+
filtered_types = var_types.select {|var_type| var_type.name.name == test_type.name.name }
|
1095
|
+
if filtered_types.empty?
|
1096
|
+
test_type.instance_type
|
1097
|
+
else
|
1098
|
+
filtered_types
|
1099
|
+
end
|
1100
|
+
}
|
1101
|
+
var_types.reject! {|type|
|
1102
|
+
var_types_in_body.any? {|test_type|
|
1103
|
+
test_type.name.name == type.name.name
|
1104
|
+
}
|
1105
|
+
}
|
1106
|
+
|
1107
|
+
type_case_override = var_names.each.with_object({}) do |var_name, hash|
|
1108
|
+
hash[var_name] = union_type(*var_types_in_body)
|
1109
|
+
end
|
1110
|
+
else
|
1111
|
+
type_case_override = nil
|
1112
|
+
end
|
1113
|
+
|
1114
|
+
for_branch(body, type_case_override: type_case_override).yield_self do |body_construction|
|
1115
|
+
type = body_construction.synthesize(body)
|
1116
|
+
pairs << [type, body_construction.type_env]
|
1117
|
+
end
|
1118
|
+
else
|
1119
|
+
pairs << [Types.nil_instance, nil]
|
1120
|
+
end
|
1121
|
+
else
|
1122
|
+
if clause
|
1123
|
+
if var_types
|
1124
|
+
if !var_types.empty?
|
1125
|
+
type_case_override = var_names.each.with_object({}) do |var_name, hash|
|
1126
|
+
hash[var_name] = union_type(*var_types)
|
1127
|
+
end
|
1128
|
+
var_types.clear
|
1129
|
+
else
|
1130
|
+
typing.add_error Errors::ElseOnExhaustiveCase.new(node: node, type: cond_type)
|
1131
|
+
type_case_override = var_names.each.with_object({}) do |var_name, hash|
|
1132
|
+
hash[var_name] = Types.any
|
1133
|
+
end
|
1134
|
+
end
|
1135
|
+
end
|
1136
|
+
|
1137
|
+
for_branch(clause, type_case_override: type_case_override).yield_self do |body_construction|
|
1138
|
+
type = body_construction.synthesize(clause)
|
1139
|
+
pairs << [type, body_construction.type_env]
|
1140
|
+
end
|
1141
|
+
end
|
1142
|
+
end
|
1143
|
+
end
|
427
1144
|
|
428
|
-
|
429
|
-
|
1145
|
+
types = pairs.map(&:first)
|
1146
|
+
envs = pairs.map(&:last)
|
430
1147
|
|
431
|
-
|
432
|
-
|
1148
|
+
if var_types
|
1149
|
+
unless var_types.empty? || whens.last
|
1150
|
+
types.push Types.nil_instance
|
1151
|
+
end
|
1152
|
+
end
|
433
1153
|
|
434
|
-
|
435
|
-
|
436
|
-
raise "Unexpected non pair: #{pair.inspect}" unless pair.type == :pair
|
437
|
-
each_child_node(pair) do |e|
|
438
|
-
synthesize(e)
|
1154
|
+
type_env.join!(envs.compact)
|
1155
|
+
typing.add_typing(node, union_type(*types))
|
439
1156
|
end
|
440
|
-
end
|
441
|
-
|
442
|
-
typing.add_typing(node, Types::Any.new)
|
443
|
-
|
444
|
-
when :dstr
|
445
|
-
each_child_node(node) do |child|
|
446
|
-
synthesize(child)
|
447
|
-
end
|
448
1157
|
|
449
|
-
|
1158
|
+
when :rescue
|
1159
|
+
yield_self do
|
1160
|
+
body, *resbodies, else_node = node.children
|
1161
|
+
body_type = synthesize(body) if body
|
450
1162
|
|
451
|
-
|
452
|
-
|
453
|
-
synthesize(child)
|
454
|
-
end
|
1163
|
+
resbody_pairs = resbodies.map do |resbody|
|
1164
|
+
exn_classes, assignment, body = resbody.children
|
455
1165
|
|
456
|
-
|
1166
|
+
if exn_classes
|
1167
|
+
case exn_classes.type
|
1168
|
+
when :array
|
1169
|
+
exn_types = exn_classes.children.map {|child| synthesize(child) }
|
1170
|
+
else
|
1171
|
+
Steep.logger.error "Unexpected exception list: #{exn_classes.type}"
|
1172
|
+
end
|
1173
|
+
end
|
457
1174
|
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
1175
|
+
if assignment
|
1176
|
+
case assignment.type
|
1177
|
+
when :lvasgn
|
1178
|
+
var_name = assignment.children[0].name
|
1179
|
+
else
|
1180
|
+
Steep.logger.error "Unexpected rescue variable assignment: #{assignment.type}"
|
1181
|
+
end
|
1182
|
+
end
|
463
1183
|
|
464
|
-
|
1184
|
+
type_override = {}
|
1185
|
+
|
1186
|
+
case
|
1187
|
+
when exn_classes && var_name
|
1188
|
+
instance_types = exn_types.map do |type|
|
1189
|
+
case
|
1190
|
+
when type.is_a?(AST::Types::Name) && type.name.is_a?(TypeName::Class)
|
1191
|
+
type.instance_type
|
1192
|
+
else
|
1193
|
+
Types.any
|
1194
|
+
end
|
1195
|
+
end
|
1196
|
+
type_override[var_name] = AST::Types::Union.build(types: instance_types)
|
1197
|
+
when var_name
|
1198
|
+
type_override[var_name] = Types.any
|
1199
|
+
end
|
465
1200
|
|
466
|
-
|
467
|
-
annots = source.annotations(block: node)
|
1201
|
+
resbody_construction = for_branch(resbody, type_case_override: type_override)
|
468
1202
|
|
469
|
-
|
1203
|
+
type = if body
|
1204
|
+
resbody_construction.synthesize(body)
|
1205
|
+
else
|
1206
|
+
Types.nil_instance
|
1207
|
+
end
|
1208
|
+
[type, resbody_construction.type_env]
|
1209
|
+
end
|
1210
|
+
resbody_types, resbody_envs = resbody_pairs.transpose
|
470
1211
|
|
471
|
-
|
472
|
-
|
473
|
-
|
1212
|
+
if else_node
|
1213
|
+
else_construction = for_branch(else_node)
|
1214
|
+
else_type = else_construction.synthesize(else_node)
|
1215
|
+
else_env = else_construction.type_env
|
1216
|
+
end
|
474
1217
|
|
475
|
-
|
1218
|
+
type_env.join!([*resbody_envs, else_env].compact)
|
476
1219
|
|
477
|
-
|
478
|
-
|
479
|
-
signature.self_type,
|
480
|
-
ty])
|
481
|
-
else
|
482
|
-
instance_type = Types::Merge.new(types: [Types::Name.instance(name: :Object),
|
483
|
-
ty])
|
1220
|
+
types = [body_type, *resbody_types, else_type].compact
|
1221
|
+
typing.add_typing(node, union_type(*types))
|
484
1222
|
end
|
485
1223
|
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
1224
|
+
when :resbody
|
1225
|
+
yield_self do
|
1226
|
+
klasses, asgn, body = node.children
|
1227
|
+
synthesize(klasses) if klasses
|
1228
|
+
synthesize(asgn) if asgn
|
1229
|
+
body_type = synthesize(body) if body
|
1230
|
+
typing.add_typing(node, body_type)
|
1231
|
+
end
|
491
1232
|
|
492
|
-
|
493
|
-
|
494
|
-
|
1233
|
+
when :ensure
|
1234
|
+
yield_self do
|
1235
|
+
body, ensure_body = node.children
|
1236
|
+
body_type = synthesize(body) if body
|
1237
|
+
synthesize(ensure_body) if ensure_body
|
1238
|
+
typing.add_typing(node, union_type(body_type))
|
1239
|
+
end
|
495
1240
|
|
496
|
-
|
497
|
-
|
498
|
-
end
|
1241
|
+
when :masgn
|
1242
|
+
type_masgn(node)
|
499
1243
|
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
const_types: annots.const_types
|
504
|
-
)
|
1244
|
+
when :while, :while_post, :until, :until_post
|
1245
|
+
yield_self do
|
1246
|
+
cond, body = node.children
|
505
1247
|
|
506
|
-
|
507
|
-
|
508
|
-
source: source,
|
509
|
-
annotations: annots,
|
510
|
-
var_types: {},
|
511
|
-
typing: typing,
|
512
|
-
method_context: nil,
|
513
|
-
block_context: nil,
|
514
|
-
module_context: module_context_,
|
515
|
-
self_type: module_context_.module_type
|
516
|
-
)
|
1248
|
+
synthesize(cond)
|
1249
|
+
truthy_vars = node.type == :while ? TypeConstruction.truthy_variables(cond) : Set.new
|
517
1250
|
|
518
|
-
|
519
|
-
|
1251
|
+
if body
|
1252
|
+
for_loop = for_branch(body, truthy_vars: truthy_vars).with(break_context: BreakContext.new(break_type: nil, next_type: nil))
|
1253
|
+
for_loop.synthesize(body)
|
1254
|
+
type_env.join!([for_loop.type_env])
|
1255
|
+
end
|
520
1256
|
|
521
|
-
|
1257
|
+
typing.add_typing(node, Types.any)
|
1258
|
+
end
|
522
1259
|
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
fallback_to_any node
|
528
|
-
end
|
1260
|
+
when :irange, :erange
|
1261
|
+
types = node.children.map {|n| synthesize(n) }
|
1262
|
+
type = Types.range_instance(union_type(*types))
|
1263
|
+
typing.add_typing(node, type)
|
529
1264
|
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
end
|
1265
|
+
when :regexp
|
1266
|
+
each_child_node(node) do |child|
|
1267
|
+
synthesize(child)
|
1268
|
+
end
|
535
1269
|
|
536
|
-
|
537
|
-
typing.add_typing(node, type)
|
538
|
-
else
|
539
|
-
fallback_to_any node
|
540
|
-
end
|
1270
|
+
typing.add_typing(node, AST::Types::Name.new_instance(name: "::Regexp"))
|
541
1271
|
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
block_type = method_context.block_type
|
546
|
-
block_type.params.flat_unnamed_params.map(&:last).zip(node.children).each do |(type, node)|
|
547
|
-
if node && type
|
548
|
-
check(node, type) do |_, rhs_type|
|
549
|
-
typing.add_error(Errors::IncompatibleAssignment.new(node: node, lhs_type: type, rhs_type: rhs_type))
|
550
|
-
end
|
551
|
-
end
|
552
|
-
end
|
1272
|
+
when :regopt
|
1273
|
+
# ignore
|
1274
|
+
typing.add_typing(node, Types.any)
|
553
1275
|
|
554
|
-
|
555
|
-
|
556
|
-
typing.add_error(Errors::UnexpectedYield.new(node: node))
|
557
|
-
fallback_to_any node
|
558
|
-
end
|
559
|
-
else
|
560
|
-
fallback_to_any node
|
561
|
-
end
|
1276
|
+
when :nth_ref, :back_ref
|
1277
|
+
typing.add_typing(node, Types.string_instance)
|
562
1278
|
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
typing.add_error(Errors::UnexpectedSuper.new(node: node, method: method_context.name))
|
569
|
-
fallback_to_any node
|
1279
|
+
when :or_asgn, :and_asgn
|
1280
|
+
yield_self do
|
1281
|
+
_, rhs = node.children
|
1282
|
+
rhs_type = synthesize(rhs)
|
1283
|
+
typing.add_typing(node, rhs_type)
|
570
1284
|
end
|
571
|
-
else
|
572
|
-
fallback_to_any node
|
573
|
-
end
|
574
1285
|
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
else
|
579
|
-
types = node.children.map {|e| synthesize(e) }
|
580
|
-
|
581
|
-
if types.uniq.size == 1
|
582
|
-
typing.add_typing(node, Types::Name.instance(name: :Array, params: [types.first]))
|
583
|
-
else
|
584
|
-
typing.add_typing(node, Types::Name.instance(name: :Array, params: [Types::Any.new]))
|
1286
|
+
when :defined?
|
1287
|
+
each_child_node(node) do |child|
|
1288
|
+
synthesize(child)
|
585
1289
|
end
|
586
|
-
end
|
587
1290
|
|
588
|
-
|
589
|
-
types = each_child_node(node).map {|child| synthesize(child) }
|
590
|
-
typing.add_typing(node, types.last)
|
1291
|
+
typing.add_typing(node, Types.any)
|
591
1292
|
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
1293
|
+
when :gvasgn
|
1294
|
+
yield_self do
|
1295
|
+
name, rhs = node.children
|
1296
|
+
type = checker.builder.signatures.find_gvar(name)&.type
|
596
1297
|
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
1298
|
+
if type
|
1299
|
+
check(rhs, type) do |_, rhs_type, result|
|
1300
|
+
typing.add_error(Errors::IncompatibleAssignment.new(node: node,
|
1301
|
+
lhs_type: type,
|
1302
|
+
rhs_type: rhs_type,
|
1303
|
+
result: result))
|
1304
|
+
end
|
1305
|
+
else
|
1306
|
+
synthesize(rhs)
|
1307
|
+
fallback_to_any node
|
1308
|
+
end
|
1309
|
+
end
|
602
1310
|
|
603
|
-
|
1311
|
+
when :gvar
|
1312
|
+
yield_self do
|
1313
|
+
name = node.children.first
|
1314
|
+
type = checker.builder.signatures.find_gvar(name)&.type
|
604
1315
|
|
605
|
-
|
606
|
-
|
1316
|
+
if type
|
1317
|
+
typing.add_typing(node, type)
|
1318
|
+
else
|
1319
|
+
fallback_to_any node
|
1320
|
+
end
|
1321
|
+
end
|
607
1322
|
|
608
|
-
|
1323
|
+
when :splat, :block_pass, :blockarg, :sclass
|
1324
|
+
yield_self do
|
1325
|
+
Steep.logger.error "Unsupported node #{node.type}"
|
609
1326
|
|
610
|
-
|
611
|
-
if clause&.type == :when
|
612
|
-
clause.children.take(clause.children.size - 1).map do |child|
|
1327
|
+
each_child_node node do |child|
|
613
1328
|
synthesize(child)
|
614
1329
|
end
|
615
1330
|
|
616
|
-
|
617
|
-
synthesize body
|
618
|
-
else
|
619
|
-
fallback_to_any body
|
620
|
-
end
|
621
|
-
else
|
622
|
-
synthesize clause if clause
|
1331
|
+
typing.add_typing node, Types.any
|
623
1332
|
end
|
624
|
-
end
|
625
1333
|
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
raise "Unexpected node: #{node.inspect}, #{node.location.line}"
|
1334
|
+
else
|
1335
|
+
raise "Unexpected node: #{node.inspect}, #{node.location.expression}"
|
1336
|
+
end
|
630
1337
|
end
|
631
1338
|
end
|
632
1339
|
|
633
1340
|
def check(node, type)
|
634
1341
|
type_ = synthesize(node)
|
635
1342
|
|
636
|
-
|
637
|
-
|
1343
|
+
result = checker.check(
|
1344
|
+
Subtyping::Relation.new(sub_type: type_,
|
1345
|
+
super_type: type),
|
1346
|
+
constraints: Subtyping::Constraints.empty
|
1347
|
+
)
|
1348
|
+
if result.failure?
|
1349
|
+
yield(type, type_, result)
|
638
1350
|
end
|
639
1351
|
end
|
640
1352
|
|
641
1353
|
def type_assignment(var, rhs, node)
|
642
|
-
lhs_type = variable_type(var)
|
643
|
-
|
644
1354
|
if rhs
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
end
|
649
|
-
typing.add_var_type(var, lhs_type)
|
650
|
-
typing.add_typing(node, lhs_type)
|
651
|
-
var_types[var] = lhs_type
|
652
|
-
lhs_type
|
653
|
-
else
|
654
|
-
rhs_type = synthesize(rhs)
|
655
|
-
typing.add_var_type(var, rhs_type)
|
656
|
-
typing.add_typing(node, rhs_type)
|
657
|
-
var_types[var] = rhs_type
|
658
|
-
rhs_type
|
659
|
-
end
|
1355
|
+
rhs_type = synthesize(rhs)
|
1356
|
+
node_type = assign_type_to_variable(var, rhs_type, node)
|
1357
|
+
typing.add_typing(node, node_type)
|
660
1358
|
else
|
1359
|
+
raise
|
1360
|
+
lhs_type = variable_type(var)
|
1361
|
+
|
661
1362
|
if lhs_type
|
662
1363
|
typing.add_var_type(var, lhs_type)
|
663
1364
|
typing.add_typing(node, lhs_type)
|
664
1365
|
var_types[var] = lhs_type
|
665
1366
|
else
|
666
|
-
typing.add_var_type(var, Types
|
1367
|
+
typing.add_var_type(var, Types.any)
|
667
1368
|
fallback_to_any node
|
668
|
-
var_types[var] = Types
|
1369
|
+
var_types[var] = Types.any
|
669
1370
|
end
|
670
1371
|
end
|
671
1372
|
end
|
672
1373
|
|
673
|
-
def
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
1374
|
+
def assign_type_to_variable(var, type, node)
|
1375
|
+
name = var.name
|
1376
|
+
type_env.assign(lvar: name, type: type) do |result|
|
1377
|
+
var_type = type_env.get(lvar: name)
|
1378
|
+
typing.add_error(Errors::IncompatibleAssignment.new(node: node,
|
1379
|
+
lhs_type: var_type,
|
1380
|
+
rhs_type: type,
|
1381
|
+
result: result))
|
1382
|
+
end
|
1383
|
+
end
|
678
1384
|
|
679
|
-
|
680
|
-
|
1385
|
+
def type_ivasgn(name, rhs, node)
|
1386
|
+
rhs_type = synthesize(rhs)
|
1387
|
+
ivar_type = type_env.assign(ivar: name, type: rhs_type) do |error|
|
1388
|
+
case error
|
1389
|
+
when Subtyping::Result::Failure
|
1390
|
+
type = type_env.get(ivar: name)
|
1391
|
+
typing.add_error(Errors::IncompatibleAssignment.new(node: node,
|
1392
|
+
lhs_type: type,
|
1393
|
+
rhs_type: rhs_type,
|
1394
|
+
result: error))
|
1395
|
+
when nil
|
1396
|
+
fallback_to_any node
|
681
1397
|
end
|
1398
|
+
end
|
1399
|
+
typing.add_typing(node, ivar_type)
|
1400
|
+
end
|
682
1401
|
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
1402
|
+
def type_masgn(node)
|
1403
|
+
lhs, rhs = node.children
|
1404
|
+
rhs_type = synthesize(rhs)
|
1405
|
+
|
1406
|
+
case
|
1407
|
+
when rhs.type == :array && lhs.children.all? {|a| a.type == :lvasgn || a.type == :ivasgn } && lhs.children.size == rhs.children.size
|
1408
|
+
pairs = lhs.children.zip(rhs.children)
|
1409
|
+
pairs.each do |(l, r)|
|
1410
|
+
case
|
1411
|
+
when l.type == :lvasgn
|
1412
|
+
type_assignment(l.children.first, r, l)
|
1413
|
+
when l.type == :ivasgn
|
1414
|
+
type_ivasgn(l.children.first, r, l)
|
1415
|
+
end
|
1416
|
+
end
|
690
1417
|
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
1418
|
+
typing.add_typing(node, rhs_type)
|
1419
|
+
|
1420
|
+
when rhs_type.is_a?(AST::Types::Any)
|
1421
|
+
fallback_to_any(node)
|
1422
|
+
|
1423
|
+
when rhs_type.is_a?(AST::Types::Name) && rhs_type.name.is_a?(TypeName::Instance) && rhs_type.name.name == ModuleName.new(name: "Array", absolute: true)
|
1424
|
+
element_type = rhs_type.args.first
|
1425
|
+
|
1426
|
+
lhs.children.each do |assignment|
|
1427
|
+
case assignment.type
|
1428
|
+
when :lvasgn
|
1429
|
+
assign_type_to_variable(assignment.children.first, element_type, assignment)
|
1430
|
+
when :ivasgn
|
1431
|
+
assignment.children.first.yield_self do |ivar|
|
1432
|
+
type_env.assign(ivar: ivar, type: element_type) do |error|
|
1433
|
+
case error
|
1434
|
+
when Subtyping::Result::Failure
|
1435
|
+
type = type_env.get(ivar: ivar)
|
1436
|
+
typing.add_error(Errors::IncompatibleAssignment.new(node: assignment,
|
1437
|
+
lhs_type: type,
|
1438
|
+
rhs_type: element_type,
|
1439
|
+
result: error))
|
1440
|
+
when nil
|
1441
|
+
fallback_to_any node
|
697
1442
|
end
|
698
1443
|
end
|
699
1444
|
end
|
1445
|
+
end
|
1446
|
+
end
|
700
1447
|
|
701
|
-
|
702
|
-
unless types.empty?
|
703
|
-
compacted_types = assignability.compact(types)
|
1448
|
+
typing.add_typing node, rhs_type
|
704
1449
|
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
1450
|
+
when rhs_type.is_a?(AST::Types::Union) &&
|
1451
|
+
rhs_type.types.all? {|type| type.is_a?(AST::Types::Name) && type.name.is_a?(TypeName::Instance) && type.name.name == ModuleName.new(name: "Array", absolute: true) }
|
1452
|
+
|
1453
|
+
types = rhs_type.types.flat_map do |type|
|
1454
|
+
type.args.first
|
1455
|
+
end
|
1456
|
+
|
1457
|
+
element_type = AST::Types::Union.build(types: types)
|
1458
|
+
|
1459
|
+
lhs.children.each do |assignment|
|
1460
|
+
case assignment.type
|
1461
|
+
when :lvasgn
|
1462
|
+
assign_type_to_variable(assignment.children.first, element_type, assignment)
|
1463
|
+
when :ivasgn
|
1464
|
+
assignment.children.first.yield_self do |ivar|
|
1465
|
+
type_env.assign(ivar: ivar, type: element_type) do |error|
|
1466
|
+
case error
|
1467
|
+
when Subtyping::Result::Failure
|
1468
|
+
type = type_env.get(ivar: ivar)
|
1469
|
+
typing.add_error(Errors::IncompatibleAssignment.new(node: assignment,
|
1470
|
+
lhs_type: type,
|
1471
|
+
rhs_type: element_type,
|
1472
|
+
result: error))
|
1473
|
+
when nil
|
1474
|
+
fallback_to_any node
|
709
1475
|
end
|
710
1476
|
end
|
711
1477
|
end
|
712
|
-
|
713
|
-
type.instantiate(subst: subst)
|
714
1478
|
end
|
715
1479
|
end
|
716
|
-
end.compact.first
|
717
1480
|
|
718
|
-
|
719
|
-
|
720
|
-
return_type = yield(receiver_type, method_name, method_type)
|
721
|
-
end
|
722
|
-
return_type || method_type.return_type
|
1481
|
+
typing.add_typing node, rhs_type
|
1482
|
+
|
723
1483
|
else
|
724
|
-
|
1484
|
+
Steep.logger.error("Unsupported masgn: #{rhs.type} (#{rhs_type})")
|
1485
|
+
fallback_to_any(node)
|
1486
|
+
end
|
1487
|
+
end
|
1488
|
+
|
1489
|
+
def type_send(node, send_node:, block_params:, block_body:, unwrap: false)
|
1490
|
+
receiver, method_name, *arguments = send_node.children
|
1491
|
+
receiver_type = receiver ? synthesize(receiver) : self_type
|
1492
|
+
arguments.each do |arg|
|
1493
|
+
if arg.type == :splat
|
1494
|
+
type = synthesize(arg.children[0])
|
1495
|
+
typing.add_typing(arg, Types.array_instance(type))
|
1496
|
+
else
|
725
1497
|
synthesize(arg)
|
726
1498
|
end
|
1499
|
+
end
|
727
1500
|
|
728
|
-
|
729
|
-
|
1501
|
+
if unwrap
|
1502
|
+
receiver_type = TypeConstruction.unwrap(receiver_type)
|
730
1503
|
end
|
731
|
-
end
|
732
1504
|
|
733
|
-
|
734
|
-
|
735
|
-
|
1505
|
+
case receiver_type
|
1506
|
+
when AST::Types::Any
|
1507
|
+
typing.add_typing node, Types.any
|
1508
|
+
|
1509
|
+
when nil
|
1510
|
+
fallback_to_any node
|
1511
|
+
|
1512
|
+
else
|
1513
|
+
begin
|
1514
|
+
interface = checker.resolve(receiver_type, with_initialize: false)
|
1515
|
+
method = interface.methods[method_name]
|
736
1516
|
|
737
|
-
if receiver_type
|
738
|
-
ret_type = assignability.method_type receiver_type, method_name do |method|
|
739
1517
|
if method
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
1518
|
+
args = TypeInference::SendArgs.from_nodes(arguments)
|
1519
|
+
return_type_or_error = type_method_call(node,
|
1520
|
+
method: method,
|
1521
|
+
args: args,
|
1522
|
+
block_params: block_params,
|
1523
|
+
block_body: block_body,
|
1524
|
+
receiver_type: receiver_type)
|
1525
|
+
|
1526
|
+
if return_type_or_error.is_a?(Errors::Base)
|
1527
|
+
fallback_to_any node do
|
1528
|
+
return_type_or_error
|
1529
|
+
end
|
1530
|
+
else
|
1531
|
+
typing.add_typing node, return_type_or_error
|
1532
|
+
end
|
1533
|
+
else
|
1534
|
+
fallback_to_any node do
|
1535
|
+
Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
1536
|
+
end
|
1537
|
+
end
|
1538
|
+
rescue Subtyping::Check::CannotResolveError
|
1539
|
+
fallback_to_any node do
|
1540
|
+
Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
1541
|
+
end
|
1542
|
+
end
|
1543
|
+
end
|
1544
|
+
end
|
1545
|
+
|
1546
|
+
def type_method_call(node, receiver_type:, method:, args:, block_params:, block_body:)
|
1547
|
+
results = method.types.map do |method_type|
|
1548
|
+
Steep.logger.tagged method_type.location&.source do
|
1549
|
+
arg_pairs = args.zip(method_type.params)
|
1550
|
+
|
1551
|
+
if arg_pairs
|
1552
|
+
try_method_type(node,
|
1553
|
+
receiver_type: receiver_type,
|
1554
|
+
method_type: method_type,
|
1555
|
+
arg_pairs: arg_pairs,
|
1556
|
+
block_params: block_params,
|
1557
|
+
block_body: block_body)
|
747
1558
|
else
|
748
|
-
|
749
|
-
|
750
|
-
nil
|
1559
|
+
Steep.logger.debug(node.inspect)
|
1560
|
+
Errors::IncompatibleArguments.new(node: node, receiver_type: receiver_type, method_type: method_type)
|
751
1561
|
end
|
752
1562
|
end
|
1563
|
+
end
|
753
1564
|
|
754
|
-
|
1565
|
+
if results.all? {|result| result.is_a?(Errors::Base) }
|
1566
|
+
results.first
|
755
1567
|
else
|
756
|
-
|
1568
|
+
results.find do |result|
|
1569
|
+
!result.is_a?(Errors::Base)
|
1570
|
+
end
|
757
1571
|
end
|
758
1572
|
end
|
759
1573
|
|
760
|
-
def
|
761
|
-
|
1574
|
+
def try_method_type(node, receiver_type:, method_type:, arg_pairs:, block_params:, block_body:)
|
1575
|
+
fresh_types = method_type.type_params.map {|x| AST::Types::Var.fresh(x) }
|
1576
|
+
fresh_vars = Set.new(fresh_types.map(&:name))
|
1577
|
+
instantiation = Interface::Substitution.build(method_type.type_params, fresh_types)
|
1578
|
+
|
1579
|
+
method_type.instantiate(instantiation).yield_self do |method_type|
|
1580
|
+
constraints = Subtyping::Constraints.new(unknowns: fresh_types.map(&:name))
|
1581
|
+
variance = Subtyping::VariableVariance.from_method_type(method_type)
|
1582
|
+
occurence = Subtyping::VariableOccurence.from_method_type(method_type)
|
1583
|
+
|
1584
|
+
arg_pairs.each do |(arg_node, param_type)|
|
1585
|
+
relation = Subtyping::Relation.new(
|
1586
|
+
sub_type: typing.type_of(node: arg_node),
|
1587
|
+
super_type: param_type.subst(instantiation)
|
1588
|
+
)
|
1589
|
+
|
1590
|
+
checker.check(relation, constraints: constraints).else do |result|
|
1591
|
+
return Errors::ArgumentTypeMismatch.new(
|
1592
|
+
node: arg_node,
|
1593
|
+
receiver_type: receiver_type,
|
1594
|
+
expected: relation.super_type,
|
1595
|
+
actual: relation.sub_type
|
1596
|
+
)
|
1597
|
+
end
|
1598
|
+
end
|
1599
|
+
|
1600
|
+
if method_type.block && block_params
|
1601
|
+
block_annotations = source.annotations(block: node)
|
1602
|
+
|
1603
|
+
params = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
|
1604
|
+
block_param_pairs = params.zip(method_type.block.params)
|
1605
|
+
|
1606
|
+
unless block_param_pairs
|
1607
|
+
return Errors::IncompatibleBlockParameters.new(
|
1608
|
+
node: node,
|
1609
|
+
method_type: method_type
|
1610
|
+
)
|
1611
|
+
end
|
1612
|
+
|
1613
|
+
block_param_pairs.each do |param, type|
|
1614
|
+
if param.type
|
1615
|
+
relation = Subtyping::Relation.new(
|
1616
|
+
sub_type: type,
|
1617
|
+
super_type: absolute_type(param.type)
|
1618
|
+
)
|
1619
|
+
|
1620
|
+
checker.check(relation, constraints: constraints).else do |result|
|
1621
|
+
return Errors::BlockParameterTypeMismatch.new(
|
1622
|
+
node: param.node,
|
1623
|
+
expected: type,
|
1624
|
+
actual: param.type
|
1625
|
+
)
|
1626
|
+
end
|
1627
|
+
end
|
1628
|
+
end
|
1629
|
+
|
1630
|
+
if block_annotations.block_type
|
1631
|
+
relation = Subtyping::Relation.new(
|
1632
|
+
sub_type: absolute_type(block_annotations.block_type),
|
1633
|
+
super_type: method_type.block.return_type
|
1634
|
+
)
|
1635
|
+
|
1636
|
+
checker.check(relation, constraints: constraints).else do |result|
|
1637
|
+
typing.add_error Errors::BlockTypeMismatch.new(node: node,
|
1638
|
+
expected: method_type.block.return_type,
|
1639
|
+
actual: absolute_type(block_annotations.block_type),
|
1640
|
+
result: result)
|
1641
|
+
end
|
1642
|
+
end
|
1643
|
+
end
|
1644
|
+
|
1645
|
+
case
|
1646
|
+
when method_type.block && block_params && block_body
|
1647
|
+
Steep.logger.debug "block is okay: method_type=#{method_type}"
|
1648
|
+
Steep.logger.debug "Constraints = #{constraints}"
|
1649
|
+
|
1650
|
+
begin
|
1651
|
+
method_type.subst(constraints.solution(checker, variance: variance, variables: occurence.params)).yield_self do |method_type|
|
1652
|
+
block_annotations = source.annotations(block: node)
|
1653
|
+
|
1654
|
+
params = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
|
1655
|
+
block_param_pairs = params.zip(method_type.block.params)
|
1656
|
+
|
1657
|
+
block_type_env = type_env.dup.yield_self do |env|
|
1658
|
+
block_param_pairs.each do |param, type|
|
1659
|
+
if param.type
|
1660
|
+
env.set(lvar: param.var.name, type: absolute_type(param.type))
|
1661
|
+
else
|
1662
|
+
env.set(lvar: param.var.name, type: absolute_type(type))
|
1663
|
+
end
|
1664
|
+
end
|
1665
|
+
|
1666
|
+
env.with_annotations(
|
1667
|
+
lvar_types: block_annotations.var_types.transform_values {|annot| absolute_type(annot.type) },
|
1668
|
+
ivar_types: block_annotations.ivar_types.transform_values {|type| absolute_type(type) },
|
1669
|
+
const_types: block_annotations.const_types.transform_values {|type| absolute_type(type) }
|
1670
|
+
)
|
1671
|
+
end
|
1672
|
+
|
1673
|
+
return_type = if block_annotations.break_type
|
1674
|
+
union_type(method_type.return_type, absolute_type(block_annotations.break_type))
|
1675
|
+
else
|
1676
|
+
method_type.return_type
|
1677
|
+
end
|
1678
|
+
Steep.logger.debug("return_type = #{return_type}")
|
1679
|
+
|
1680
|
+
block_context = BlockContext.new(body_type: absolute_type(block_annotations.block_type))
|
1681
|
+
Steep.logger.debug("block_context { body_type: #{block_context.body_type} }")
|
1682
|
+
|
1683
|
+
break_context = BreakContext.new(
|
1684
|
+
break_type: absolute_type(block_annotations.break_type) || method_type.return_type,
|
1685
|
+
next_type: absolute_type(block_annotations.block_type)
|
1686
|
+
)
|
1687
|
+
Steep.logger.debug("break_context { type: #{absolute_type(break_context.break_type)} }")
|
1688
|
+
|
1689
|
+
for_block = self.class.new(
|
1690
|
+
checker: checker,
|
1691
|
+
source: source,
|
1692
|
+
annotations: annotations + block_annotations,
|
1693
|
+
type_env: block_type_env,
|
1694
|
+
block_context: block_context,
|
1695
|
+
typing: typing,
|
1696
|
+
method_context: method_context,
|
1697
|
+
module_context: module_context,
|
1698
|
+
self_type: absolute_type(block_annotations.self_type) || self_type,
|
1699
|
+
break_context: break_context
|
1700
|
+
)
|
1701
|
+
|
1702
|
+
each_child_node(block_params) do |p|
|
1703
|
+
for_block.synthesize(p)
|
1704
|
+
end
|
1705
|
+
|
1706
|
+
block_body_type = for_block.synthesize(block_body)
|
1707
|
+
|
1708
|
+
unless method_type.block.return_type.is_a?(AST::Types::Void)
|
1709
|
+
result = checker.check(Subtyping::Relation.new(
|
1710
|
+
sub_type: block_annotations.block_type || block_body_type,
|
1711
|
+
super_type: method_type.block.return_type
|
1712
|
+
), constraints: constraints)
|
1713
|
+
|
1714
|
+
if result.success?
|
1715
|
+
return_type.subst(constraints.solution(checker, variance: variance, variables: fresh_vars))
|
1716
|
+
else
|
1717
|
+
typing.add_error Errors::BlockTypeMismatch.new(node: node,
|
1718
|
+
expected: method_type.block.return_type,
|
1719
|
+
actual: block_annotations.block_type || block_body_type,
|
1720
|
+
result: result)
|
1721
|
+
return_type
|
1722
|
+
end
|
1723
|
+
else
|
1724
|
+
return_type
|
1725
|
+
end
|
1726
|
+
end
|
1727
|
+
|
1728
|
+
rescue Subtyping::Constraints::UnsatisfiableConstraint => exn
|
1729
|
+
typing.add_error Errors::UnsatisfiableConstraint.new(node: node,
|
1730
|
+
method_type: method_type,
|
1731
|
+
var: exn.var,
|
1732
|
+
sub_type: exn.sub_type,
|
1733
|
+
super_type: exn.super_type,
|
1734
|
+
result: exn.result
|
1735
|
+
)
|
1736
|
+
fallback_any_rec node
|
1737
|
+
end
|
1738
|
+
|
1739
|
+
when !method_type.block && !block_params && !block_body
|
1740
|
+
# OK, without block
|
1741
|
+
method_type.subst(constraints.solution(checker, variance: variance, variables: fresh_vars)).return_type
|
1742
|
+
|
1743
|
+
when !method_type.block && block_params && block_body
|
1744
|
+
Errors::UnexpectedBlockGiven.new(
|
1745
|
+
node: node,
|
1746
|
+
method_type: method_type
|
1747
|
+
)
|
1748
|
+
|
1749
|
+
when method_type.block && !block_params && !block_body
|
1750
|
+
Errors::RequiredBlockMissing.new(
|
1751
|
+
node: node,
|
1752
|
+
method_type: method_type
|
1753
|
+
)
|
1754
|
+
|
1755
|
+
else
|
1756
|
+
raise "Unexpected case condition"
|
1757
|
+
end
|
1758
|
+
end
|
762
1759
|
end
|
763
1760
|
|
764
1761
|
def each_child_node(node)
|
765
1762
|
if block_given?
|
766
1763
|
node.children.each do |child|
|
767
|
-
if child.is_a?(AST::Node)
|
1764
|
+
if child.is_a?(::AST::Node)
|
768
1765
|
yield child
|
769
1766
|
end
|
770
1767
|
end
|
@@ -919,7 +1916,7 @@ module Steep
|
|
919
1916
|
if type.params.rest
|
920
1917
|
a = nodes.first
|
921
1918
|
if a&.type == :restarg
|
922
|
-
env[a.children.first] = Types
|
1919
|
+
env[a.children.first] = Types.array_instance(type.params.rest)
|
923
1920
|
nodes.shift
|
924
1921
|
end
|
925
1922
|
end
|
@@ -940,8 +1937,7 @@ module Steep
|
|
940
1937
|
if node.type == :kwrestarg
|
941
1938
|
ty = type.params.rest_keywords
|
942
1939
|
if ty
|
943
|
-
env[node.children[0]] = Types
|
944
|
-
params: [Types::Name.instance(name: :Symbol), ty])
|
1940
|
+
env[node.children[0]] = Types.hash_instance(Types.symbol_instance, ty)
|
945
1941
|
end
|
946
1942
|
end
|
947
1943
|
end
|
@@ -953,46 +1949,86 @@ module Steep
|
|
953
1949
|
env.size == nodes.size && env.size == params.size
|
954
1950
|
end
|
955
1951
|
|
956
|
-
def
|
957
|
-
|
1952
|
+
def current_namespace
|
1953
|
+
module_context&.current_namespace
|
1954
|
+
end
|
1955
|
+
|
1956
|
+
def nested_namespace(new)
|
1957
|
+
case
|
1958
|
+
when !new.simple?
|
1959
|
+
current_namespace
|
1960
|
+
when current_namespace
|
1961
|
+
current_namespace + new
|
1962
|
+
else
|
1963
|
+
new.absolute!
|
1964
|
+
end
|
1965
|
+
end
|
958
1966
|
|
959
|
-
|
960
|
-
|
1967
|
+
def absolute_name(module_name)
|
1968
|
+
if current_namespace
|
1969
|
+
current_namespace + module_name
|
961
1970
|
else
|
962
|
-
|
1971
|
+
module_name.absolute!
|
963
1972
|
end
|
964
1973
|
end
|
965
1974
|
|
966
|
-
def
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
1975
|
+
def absolute_type(type)
|
1976
|
+
if type
|
1977
|
+
checker.builder.absolute_type(type, current: current_namespace)
|
1978
|
+
end
|
1979
|
+
end
|
1980
|
+
|
1981
|
+
def union_type(*types)
|
1982
|
+
AST::Types::Union.build(types: types)
|
1983
|
+
end
|
1984
|
+
|
1985
|
+
def validate_method_definitions(node, module_name)
|
1986
|
+
signature = checker.builder.signatures.find_class_or_module(module_name.name)
|
1987
|
+
|
1988
|
+
signature.members.each do |member|
|
1989
|
+
if member.is_a?(AST::Signature::Members::Method)
|
1990
|
+
if member.instance_method?
|
1991
|
+
case
|
1992
|
+
when module_context.defined_instance_methods.include?(member.name)
|
1993
|
+
# ok
|
1994
|
+
when annotations.dynamics[member.name]&.instance_method?
|
1995
|
+
# ok
|
1996
|
+
else
|
973
1997
|
typing.add_error Errors::MethodDefinitionMissing.new(node: node,
|
974
|
-
module_name:
|
1998
|
+
module_name: module_name.name,
|
975
1999
|
kind: :instance,
|
976
2000
|
missing_method: member.name)
|
977
2001
|
end
|
978
|
-
|
979
2002
|
end
|
980
|
-
|
981
|
-
|
2003
|
+
|
2004
|
+
if member.module_method?
|
2005
|
+
case
|
2006
|
+
when module_context.defined_module_methods.include?(member.name)
|
2007
|
+
# ok
|
2008
|
+
when annotations.dynamics[member.name]&.module_method?
|
2009
|
+
# ok
|
2010
|
+
else
|
982
2011
|
typing.add_error Errors::MethodDefinitionMissing.new(node: node,
|
983
|
-
module_name:
|
2012
|
+
module_name: module_name.name,
|
984
2013
|
kind: :module,
|
985
2014
|
missing_method: member.name)
|
986
2015
|
end
|
987
2016
|
end
|
988
2017
|
end
|
2018
|
+
end
|
989
2019
|
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
2020
|
+
annotations.dynamics.each do |method_name, annotation|
|
2021
|
+
method_signature = signature.members.find {|sig| sig.is_a?(AST::Signature::Members::Method) && sig.name == method_name }
|
2022
|
+
|
2023
|
+
case
|
2024
|
+
when annotation.module_method? && method_signature&.module_method?
|
2025
|
+
# ok
|
2026
|
+
when annotation.instance_method? && method_signature&.instance_method?
|
2027
|
+
# ok
|
2028
|
+
else
|
2029
|
+
typing.add_error Errors::UnexpectedDynamicMethod.new(node: node,
|
2030
|
+
module_name: module_name.name,
|
2031
|
+
method_name: method_name)
|
996
2032
|
end
|
997
2033
|
end
|
998
2034
|
end
|
@@ -1002,7 +2038,7 @@ module Steep
|
|
1002
2038
|
|
1003
2039
|
while node
|
1004
2040
|
case node.type
|
1005
|
-
when :const
|
2041
|
+
when :const, :casgn
|
1006
2042
|
path.unshift(node.children[1])
|
1007
2043
|
node = node.children[0]
|
1008
2044
|
when :cbase
|
@@ -1017,12 +2053,82 @@ module Steep
|
|
1017
2053
|
end
|
1018
2054
|
|
1019
2055
|
def fallback_to_any(node)
|
1020
|
-
|
1021
|
-
|
2056
|
+
if block_given?
|
2057
|
+
typing.add_error yield
|
2058
|
+
else
|
2059
|
+
typing.add_error Errors::FallbackAny.new(node: node)
|
2060
|
+
end
|
2061
|
+
|
2062
|
+
typing.add_typing node, Types.any
|
1022
2063
|
end
|
1023
2064
|
|
1024
2065
|
def self_class?(node)
|
1025
2066
|
node.type == :send && node.children[0]&.type == :self && node.children[1] == :class
|
1026
2067
|
end
|
2068
|
+
|
2069
|
+
def namespace_module?(node)
|
2070
|
+
nodes = case node.type
|
2071
|
+
when :class, :module
|
2072
|
+
node.children.last&.yield_self {|child|
|
2073
|
+
if child.type == :begin
|
2074
|
+
child.children
|
2075
|
+
else
|
2076
|
+
[child]
|
2077
|
+
end
|
2078
|
+
} || []
|
2079
|
+
else
|
2080
|
+
return false
|
2081
|
+
end
|
2082
|
+
|
2083
|
+
!nodes.empty? && nodes.all? {|child| child.type == :class || child.type == :module }
|
2084
|
+
end
|
2085
|
+
|
2086
|
+
def fallback_any_rec(node)
|
2087
|
+
fallback_to_any(node) unless typing.has_type?(node)
|
2088
|
+
|
2089
|
+
each_child_node(node) do |child|
|
2090
|
+
fallback_any_rec(child)
|
2091
|
+
end
|
2092
|
+
|
2093
|
+
typing.type_of(node: node)
|
2094
|
+
end
|
2095
|
+
|
2096
|
+
def self.unwrap(type)
|
2097
|
+
case
|
2098
|
+
when type.is_a?(AST::Types::Union)
|
2099
|
+
types = type.types.reject {|type| type.is_a?(AST::Types::Name) && type.name == TypeName::Instance.new(name: ModuleName.parse("::NilClass")) }
|
2100
|
+
AST::Types::Union.build(types: types)
|
2101
|
+
else
|
2102
|
+
type
|
2103
|
+
end
|
2104
|
+
end
|
2105
|
+
|
2106
|
+
def self.truthy_variables(node)
|
2107
|
+
case node&.type
|
2108
|
+
when :lvar
|
2109
|
+
Set.new([node.children.first.name])
|
2110
|
+
when :lvasgn
|
2111
|
+
Set.new([node.children.first.name]) + truthy_variables(node.children[1])
|
2112
|
+
when :and
|
2113
|
+
truthy_variables(node.children[0]) + truthy_variables(node.children[1])
|
2114
|
+
when :begin
|
2115
|
+
truthy_variables(node.children.last)
|
2116
|
+
else
|
2117
|
+
Set.new()
|
2118
|
+
end
|
2119
|
+
end
|
2120
|
+
|
2121
|
+
def self.value_variables(node)
|
2122
|
+
case node&.type
|
2123
|
+
when :lvar
|
2124
|
+
Set.new([node.children.first.name])
|
2125
|
+
when :lvasgn
|
2126
|
+
Set.new([node.children.first.name]) + value_variables(node.children[1])
|
2127
|
+
when :begin
|
2128
|
+
value_variables(node.children.last)
|
2129
|
+
else
|
2130
|
+
Set.new
|
2131
|
+
end
|
2132
|
+
end
|
1027
2133
|
end
|
1028
2134
|
end
|