typeprof 0.30.0 → 0.31.0
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/README.md +23 -4
- data/doc/doc.ja.md +1 -1
- data/lib/typeprof/cli/cli.rb +28 -10
- data/lib/typeprof/cli.rb +1 -0
- data/lib/typeprof/code_range.rb +9 -7
- data/lib/typeprof/core/ast/base.rb +27 -10
- data/lib/typeprof/core/ast/call.rb +90 -21
- data/lib/typeprof/core/ast/const.rb +7 -12
- data/lib/typeprof/core/ast/control.rb +349 -74
- data/lib/typeprof/core/ast/meta.rb +5 -5
- data/lib/typeprof/core/ast/method.rb +19 -5
- data/lib/typeprof/core/ast/misc.rb +21 -2
- data/lib/typeprof/core/ast/module.rb +10 -7
- data/lib/typeprof/core/ast/pattern.rb +9 -1
- data/lib/typeprof/core/ast/sig_decl.rb +163 -42
- data/lib/typeprof/core/ast/sig_type.rb +394 -24
- data/lib/typeprof/core/ast/value.rb +11 -3
- data/lib/typeprof/core/ast/variable.rb +32 -2
- data/lib/typeprof/core/ast.rb +15 -4
- data/lib/typeprof/core/builtin.rb +15 -9
- data/lib/typeprof/core/env/method.rb +21 -16
- data/lib/typeprof/core/env/method_entity.rb +11 -2
- data/lib/typeprof/core/env/module_entity.rb +57 -0
- data/lib/typeprof/core/env/narrowing.rb +131 -0
- data/lib/typeprof/core/env/static_read.rb +9 -8
- data/lib/typeprof/core/env.rb +43 -12
- data/lib/typeprof/core/graph/box.rb +218 -101
- data/lib/typeprof/core/graph/change_set.rb +44 -37
- data/lib/typeprof/core/graph/vertex.rb +7 -21
- data/lib/typeprof/core/service.rb +61 -40
- data/lib/typeprof/core/type.rb +52 -123
- data/lib/typeprof/core.rb +1 -1
- data/lib/typeprof/diagnostic.rb +5 -6
- data/lib/typeprof/lsp/messages.rb +27 -36
- data/lib/typeprof/lsp/server.rb +144 -25
- data/lib/typeprof/lsp/text.rb +1 -0
- data/lib/typeprof/lsp/util.rb +0 -10
- data/lib/typeprof/version.rb +1 -1
- data/typeprof.conf.jsonc +22 -0
- data/typeprof.gemspec +1 -0
- metadata +19 -5
- data/lib/typeprof/core/graph.rb +0 -3
|
@@ -39,18 +39,12 @@ module TypeProf::Core
|
|
|
39
39
|
@changes.reinstall(genv)
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
def
|
|
43
|
-
raise
|
|
44
|
-
@changes.diagnostics.each(&blk)
|
|
45
|
-
@changes.boxes.each_value do |box|
|
|
46
|
-
box.diagnostics(genv, &blk)
|
|
47
|
-
end
|
|
42
|
+
def run0(genv, changes)
|
|
43
|
+
raise NotImplementedError
|
|
48
44
|
end
|
|
49
45
|
|
|
50
|
-
#@@new_id = 0
|
|
51
|
-
|
|
52
46
|
def to_s
|
|
53
|
-
"#{ self.class.to_s.split("::").last
|
|
47
|
+
"#{ self.class.to_s.split("::").last }#{ @id ||= $new_id += 1 }"
|
|
54
48
|
end
|
|
55
49
|
|
|
56
50
|
alias inspect to_s
|
|
@@ -87,7 +81,20 @@ module TypeProf::Core
|
|
|
87
81
|
attr_reader :node, :rbs_type, :ret
|
|
88
82
|
|
|
89
83
|
def run0(genv, changes)
|
|
90
|
-
|
|
84
|
+
# Create substitution map for type parameters if we're in a SigInstanceVariableNode within a generic class
|
|
85
|
+
subst = {}
|
|
86
|
+
if @node.is_a?(AST::SigInstanceVariableNode) && @node.cpath
|
|
87
|
+
mod = genv.resolve_cpath(@node.cpath)
|
|
88
|
+
if mod.type_params && !mod.type_params.empty?
|
|
89
|
+
# Create a substitution map where each type parameter maps to a type variable vertex
|
|
90
|
+
subst = mod.type_params.to_h do |param|
|
|
91
|
+
type_var_vtx = Vertex.new(@node)
|
|
92
|
+
[param, type_var_vtx]
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
vtx = @rbs_type.covariant_vertex(genv, changes, subst)
|
|
91
98
|
changes.add_edge(genv, vtx, @ret)
|
|
92
99
|
end
|
|
93
100
|
end
|
|
@@ -142,13 +149,11 @@ module TypeProf::Core
|
|
|
142
149
|
end
|
|
143
150
|
|
|
144
151
|
method_type.req_positionals.each_with_index do |ty, i|
|
|
145
|
-
|
|
146
|
-
return false unless a_args.positionals[i].check_match(genv, changes, f_arg)
|
|
152
|
+
return false unless ty.typecheck(genv, changes, a_args.positionals[i], param_map)
|
|
147
153
|
end
|
|
148
154
|
method_type.post_positionals.each_with_index do |ty, i|
|
|
149
|
-
f_arg = ty.contravariant_vertex(genv, changes, param_map)
|
|
150
155
|
i -= method_type.post_positionals.size
|
|
151
|
-
return false unless a_args.positionals[i]
|
|
156
|
+
return false unless ty.typecheck(genv, changes, a_args.positionals[i], param_map)
|
|
152
157
|
end
|
|
153
158
|
|
|
154
159
|
start_rest = method_type.req_positionals.size
|
|
@@ -157,61 +162,100 @@ module TypeProf::Core
|
|
|
157
162
|
i = 0
|
|
158
163
|
while i < method_type.opt_positionals.size && start_rest < end_rest
|
|
159
164
|
break if a_args.splat_flags[start_rest]
|
|
160
|
-
|
|
161
|
-
return false unless a_args.positionals[start_rest].check_match(genv, changes, f_arg)
|
|
165
|
+
return false unless method_type.opt_positionals[i].typecheck(genv, changes, a_args.positionals[start_rest], param_map)
|
|
162
166
|
i += 1
|
|
163
167
|
start_rest += 1
|
|
164
168
|
end
|
|
165
169
|
|
|
166
170
|
if start_rest < end_rest
|
|
167
|
-
vtxs = a_args.get_rest_args(genv, start_rest, end_rest)
|
|
171
|
+
vtxs = a_args.get_rest_args(genv, changes, start_rest, end_rest)
|
|
168
172
|
while i < method_type.opt_positionals.size
|
|
169
|
-
|
|
170
|
-
return false if vtxs.any? {|vtx| !
|
|
173
|
+
ty = method_type.opt_positionals[i]
|
|
174
|
+
return false if vtxs.any? {|vtx| !ty.typecheck(genv, changes, vtx, param_map) }
|
|
171
175
|
i += 1
|
|
172
176
|
end
|
|
173
177
|
if method_type.rest_positionals
|
|
174
|
-
|
|
175
|
-
return false if vtxs.any? {|vtx| !vtx.check_match(genv, changes, f_arg) }
|
|
178
|
+
return false if vtxs.any? {|vtx| !method_type.rest_positionals.typecheck(genv, changes, vtx, param_map) }
|
|
176
179
|
end
|
|
177
180
|
end
|
|
178
181
|
|
|
179
182
|
return true
|
|
180
183
|
end
|
|
181
184
|
|
|
182
|
-
def
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
method_type.type_params.zip(yield(method_type)) do |var, vtx|
|
|
188
|
-
param_map0[var] = vtx
|
|
189
|
-
end
|
|
185
|
+
def resolve_overload(changes, genv, method_type, node, param_map, a_args, ret, force)
|
|
186
|
+
param_map0 = param_map.dup
|
|
187
|
+
if method_type.type_params
|
|
188
|
+
method_type.type_params.zip(yield(method_type)) do |var, vtx|
|
|
189
|
+
param_map0[var] = vtx
|
|
190
190
|
end
|
|
191
|
+
end
|
|
191
192
|
|
|
192
|
-
|
|
193
|
+
unless match_arguments?(genv, changes, param_map0, a_args, method_type)
|
|
194
|
+
if force
|
|
195
|
+
meth = node.mid_code_range ? :mid_code_range : :code_range
|
|
196
|
+
changes.add_diagnostic(meth, "wrong type of arguments") # XXX: more friendly and fine-grained error message
|
|
197
|
+
end
|
|
198
|
+
return false
|
|
199
|
+
end
|
|
193
200
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
201
|
+
rbs_blk = method_type.block
|
|
202
|
+
if method_type.block_required && !a_args.block
|
|
203
|
+
if force
|
|
204
|
+
meth = node.mid_code_range ? :mid_code_range : :code_range
|
|
205
|
+
changes.add_diagnostic(meth, "block is expected") # XXX: more friendly error message
|
|
206
|
+
end
|
|
207
|
+
return false
|
|
208
|
+
end
|
|
209
|
+
if !rbs_blk && a_args.block
|
|
210
|
+
if force
|
|
211
|
+
meth = node.mid_code_range ? :mid_code_range : :code_range
|
|
212
|
+
changes.add_diagnostic(meth, "block is not expected") # XXX: more friendly error message
|
|
213
|
+
end
|
|
214
|
+
return false
|
|
215
|
+
end
|
|
216
|
+
if rbs_blk && a_args.block
|
|
217
|
+
# rbs_blk_func.optional_keywords, ...
|
|
218
|
+
blk_a_args = rbs_blk.req_positionals.map do |blk_a_arg|
|
|
219
|
+
blk_a_arg.covariant_vertex(genv, changes, param_map0)
|
|
220
|
+
end
|
|
221
|
+
a_args.block.each_type do |ty|
|
|
222
|
+
case ty
|
|
223
|
+
when Type::Proc
|
|
224
|
+
ty.block.accept_args(genv, changes, blk_a_args)
|
|
225
|
+
|
|
226
|
+
if ty.block.is_a?(Block)
|
|
227
|
+
ty.block.next_boxes.each do |next_box|
|
|
228
|
+
unless rbs_blk.return_type.typecheck(genv, changes, next_box.a_ret, param_map0)
|
|
229
|
+
next_box.wrong_return_type(rbs_blk.return_type.show, changes)
|
|
230
|
+
end
|
|
205
231
|
end
|
|
206
|
-
|
|
207
|
-
ty.block.accept_args(genv, changes, blk_a_args, blk_f_ret, true)
|
|
208
232
|
end
|
|
209
233
|
end
|
|
210
234
|
end
|
|
211
|
-
|
|
235
|
+
end
|
|
212
236
|
|
|
237
|
+
force = true
|
|
238
|
+
return true
|
|
239
|
+
|
|
240
|
+
ensure
|
|
241
|
+
if force
|
|
242
|
+
ret_vtx = method_type.return_type.covariant_vertex(genv, changes, param_map0)
|
|
213
243
|
changes.add_edge(genv, ret_vtx, ret)
|
|
214
|
-
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def resolve_overloads(changes, genv, node, param_map, a_args, ret, &blk)
|
|
248
|
+
if @method_types.size == 1
|
|
249
|
+
method_type = @method_types.first
|
|
250
|
+
resolve_overload(changes, genv, method_type, node, param_map, a_args, ret, true, &blk)
|
|
251
|
+
return
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
match_any_overload = false
|
|
255
|
+
@method_types.each do |method_type|
|
|
256
|
+
if resolve_overload(changes, genv, method_type, node, param_map, a_args, ret, false, &blk)
|
|
257
|
+
match_any_overload = true
|
|
258
|
+
end
|
|
215
259
|
end
|
|
216
260
|
unless match_any_overload
|
|
217
261
|
meth = node.mid_code_range ? :mid_code_range : :code_range
|
|
@@ -252,53 +296,66 @@ module TypeProf::Core
|
|
|
252
296
|
end
|
|
253
297
|
|
|
254
298
|
class EscapeBox < Box
|
|
255
|
-
def initialize(node, genv, a_ret
|
|
299
|
+
def initialize(node, genv, a_ret)
|
|
256
300
|
super(node)
|
|
257
301
|
@a_ret = a_ret.new_vertex(genv, node)
|
|
258
|
-
@f_ret = f_ret
|
|
259
|
-
@f_ret.add_edge(genv, self)
|
|
260
302
|
end
|
|
261
303
|
|
|
262
|
-
attr_reader :a_ret
|
|
304
|
+
attr_reader :a_ret
|
|
263
305
|
|
|
264
306
|
def ret = @a_ret
|
|
265
307
|
|
|
266
308
|
def run0(genv, changes)
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
309
|
+
return
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
def wrong_return_type(f_ret_show, changes)
|
|
313
|
+
actual_ty = @a_ret.show
|
|
314
|
+
return if actual_ty == "untyped" # XXX: too ad-hoc?
|
|
315
|
+
msg = "expected: #{ f_ret_show }; actual: #{ actual_ty }"
|
|
316
|
+
case @node
|
|
317
|
+
when AST::ReturnNode
|
|
318
|
+
changes.add_diagnostic(:code_range, msg, @node)
|
|
319
|
+
when AST::DefNode
|
|
320
|
+
changes.add_diagnostic(:last_stmt_code_range, msg, @node)
|
|
321
|
+
when AST::NextNode
|
|
322
|
+
changes.add_diagnostic(:code_range, msg, @node)
|
|
323
|
+
when AST::CallNode
|
|
324
|
+
changes.add_diagnostic(:block_last_stmt_code_range, msg, @node)
|
|
325
|
+
when AST::AttrReaderMetaNode, AST::AttrAccessorMetaNode
|
|
326
|
+
changes.add_diagnostic(:code_range, msg, @node)
|
|
327
|
+
else
|
|
328
|
+
pp @node.class
|
|
283
329
|
end
|
|
284
330
|
end
|
|
285
331
|
end
|
|
286
332
|
|
|
287
333
|
class SplatBox < Box
|
|
288
|
-
def initialize(node, genv, ary)
|
|
334
|
+
def initialize(node, genv, ary, idx)
|
|
289
335
|
super(node)
|
|
290
336
|
@ary = ary
|
|
337
|
+
@idx = idx
|
|
291
338
|
@ary.add_edge(genv, self)
|
|
292
339
|
@ret = Vertex.new(node)
|
|
293
340
|
end
|
|
294
341
|
|
|
295
|
-
attr_reader :ary, :ret
|
|
342
|
+
attr_reader :ary, :idx, :ret
|
|
296
343
|
|
|
297
344
|
def run0(genv, changes)
|
|
298
345
|
@ary.each_type do |ty|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
346
|
+
case ty
|
|
347
|
+
when Type::Instance
|
|
348
|
+
if ty.mod == genv.mod_ary
|
|
349
|
+
changes.add_edge(genv, ty.args[0], @ret)
|
|
350
|
+
else
|
|
351
|
+
"???"
|
|
352
|
+
end
|
|
353
|
+
when Type::Array
|
|
354
|
+
if @idx && @idx < ty.elems.size
|
|
355
|
+
changes.add_edge(genv, ty.elems[@idx], @ret)
|
|
356
|
+
else
|
|
357
|
+
changes.add_edge(genv, ty.get_elem(genv, @idx), @ret)
|
|
358
|
+
end
|
|
302
359
|
else
|
|
303
360
|
"???"
|
|
304
361
|
end
|
|
@@ -323,8 +380,8 @@ module TypeProf::Core
|
|
|
323
380
|
@hsh.each_type do |ty|
|
|
324
381
|
ty = ty.base_type(genv)
|
|
325
382
|
if ty.mod == genv.mod_hash
|
|
326
|
-
changes.add_edge(genv, ty.args[0], @unified_key)
|
|
327
|
-
changes.add_edge(genv, ty.args[1], @unified_val)
|
|
383
|
+
changes.add_edge(genv, ty.args[0].new_vertex(genv, :__hash_splat), @unified_key)
|
|
384
|
+
changes.add_edge(genv, ty.args[1].new_vertex(genv, :__hash_splat), @unified_val)
|
|
328
385
|
else
|
|
329
386
|
"???"
|
|
330
387
|
end
|
|
@@ -355,11 +412,8 @@ module TypeProf::Core
|
|
|
355
412
|
end
|
|
356
413
|
me = genv.resolve_method(@cpath, @singleton, @mid)
|
|
357
414
|
me.add_def(self)
|
|
358
|
-
if me.decls.empty?
|
|
359
|
-
|
|
360
|
-
else
|
|
361
|
-
genv.add_run(self)
|
|
362
|
-
end
|
|
415
|
+
me.add_run_all_method_call_boxes(genv) if me.decls.empty?
|
|
416
|
+
genv.add_run(self)
|
|
363
417
|
end
|
|
364
418
|
|
|
365
419
|
attr_accessor :node
|
|
@@ -369,11 +423,8 @@ module TypeProf::Core
|
|
|
369
423
|
def destroy(genv)
|
|
370
424
|
me = genv.resolve_method(@cpath, @singleton, @mid)
|
|
371
425
|
me.remove_def(self)
|
|
372
|
-
if me.decls.empty?
|
|
373
|
-
|
|
374
|
-
else
|
|
375
|
-
genv.add_run(self)
|
|
376
|
-
end
|
|
426
|
+
me.add_run_all_method_call_boxes(genv) if me.decls.empty?
|
|
427
|
+
genv.add_run(self)
|
|
377
428
|
super(genv)
|
|
378
429
|
end
|
|
379
430
|
|
|
@@ -430,8 +481,11 @@ module TypeProf::Core
|
|
|
430
481
|
if pass_arguments(changes, genv, a_args)
|
|
431
482
|
# TODO: block
|
|
432
483
|
f_ret = method_type.return_type.contravariant_vertex(genv, changes, param_map0)
|
|
484
|
+
changes.add_edge(genv, f_ret, @ret)
|
|
433
485
|
@ret_boxes.each do |ret_box|
|
|
434
|
-
|
|
486
|
+
unless method_type.return_type.typecheck(genv, changes, ret_box.a_ret, param_map0)
|
|
487
|
+
ret_box.wrong_return_type(method_type.return_type.show, changes)
|
|
488
|
+
end
|
|
435
489
|
end
|
|
436
490
|
end
|
|
437
491
|
end
|
|
@@ -451,7 +505,7 @@ module TypeProf::Core
|
|
|
451
505
|
|
|
452
506
|
start_rest = [a_args.splat_flags.index(true), @f_args.req_positionals.size + @f_args.opt_positionals.size].min
|
|
453
507
|
end_rest = [a_args.splat_flags.rindex(true) + 1, a_args.positionals.size - @f_args.post_positionals.size].max
|
|
454
|
-
rest_vtxs = a_args.get_rest_args(genv, start_rest, end_rest)
|
|
508
|
+
rest_vtxs = a_args.get_rest_args(genv, changes, start_rest, end_rest)
|
|
455
509
|
|
|
456
510
|
@f_args.req_positionals.each_with_index do |f_vtx, i|
|
|
457
511
|
if i < start_rest
|
|
@@ -485,7 +539,11 @@ module TypeProf::Core
|
|
|
485
539
|
|
|
486
540
|
if @f_args.rest_positionals
|
|
487
541
|
rest_vtxs.each do |vtx|
|
|
488
|
-
|
|
542
|
+
@f_args.rest_positionals.each_type do |ty|
|
|
543
|
+
if ty.is_a?(Type::Instance) && ty.mod == genv.mod_ary && ty.args[0]
|
|
544
|
+
changes.add_edge(genv, vtx, ty.args[0])
|
|
545
|
+
end
|
|
546
|
+
end
|
|
489
547
|
end
|
|
490
548
|
end
|
|
491
549
|
else
|
|
@@ -519,9 +577,12 @@ module TypeProf::Core
|
|
|
519
577
|
|
|
520
578
|
if start_rest < end_rest
|
|
521
579
|
if @f_args.rest_positionals
|
|
522
|
-
f_arg = @f_args.rest_positionals
|
|
523
580
|
(start_rest..end_rest-1).each do |i|
|
|
524
|
-
|
|
581
|
+
@f_args.rest_positionals.each_type do |ty|
|
|
582
|
+
if ty.is_a?(Type::Instance) && ty.mod == genv.mod_ary && ty.args[0]
|
|
583
|
+
changes.add_edge(genv, a_args.positionals[i], ty.args[0])
|
|
584
|
+
end
|
|
585
|
+
end
|
|
525
586
|
end
|
|
526
587
|
end
|
|
527
588
|
end
|
|
@@ -569,7 +630,7 @@ module TypeProf::Core
|
|
|
569
630
|
args << ("?" + Type.strip_parens(f_vtx.show))
|
|
570
631
|
end
|
|
571
632
|
if @f_args.rest_positionals
|
|
572
|
-
args << ("*" + Type.strip_parens(@f_args.rest_positionals.show))
|
|
633
|
+
args << ("*" + Type.strip_array(Type.strip_parens(@f_args.rest_positionals.show)))
|
|
573
634
|
end
|
|
574
635
|
@f_args.post_positionals.each do |var|
|
|
575
636
|
args << Type.strip_parens(var.show)
|
|
@@ -583,7 +644,7 @@ module TypeProf::Core
|
|
|
583
644
|
end
|
|
584
645
|
end
|
|
585
646
|
if @f_args.rest_keywords
|
|
586
|
-
args << "**#{ Type.strip_parens(@f_args.rest_keywords.show) }"
|
|
647
|
+
args << "**#{ Type.extract_hash_value_type(Type.strip_parens(@f_args.rest_keywords.show)) }"
|
|
587
648
|
end
|
|
588
649
|
|
|
589
650
|
if output_parameter_names && @node.is_a?(AST::DefNode)
|
|
@@ -603,7 +664,7 @@ module TypeProf::Core
|
|
|
603
664
|
args = args.join(", ")
|
|
604
665
|
s = args.empty? ? [] : ["(#{ args })"]
|
|
605
666
|
s << "#{ block_show.sort.join(" | ") }" unless block_show.empty?
|
|
606
|
-
s << "-> #{ @ret.show }"
|
|
667
|
+
s << "-> #{ @mid == :initialize ? "void" : @ret.show }"
|
|
607
668
|
s.join(" ")
|
|
608
669
|
end
|
|
609
670
|
end
|
|
@@ -619,11 +680,8 @@ module TypeProf::Core
|
|
|
619
680
|
|
|
620
681
|
me = genv.resolve_method(@cpath, @singleton, @new_mid)
|
|
621
682
|
me.add_alias(self, @old_mid)
|
|
622
|
-
if me.decls.empty?
|
|
623
|
-
|
|
624
|
-
else
|
|
625
|
-
genv.add_run(self)
|
|
626
|
-
end
|
|
683
|
+
me.add_run_all_method_call_boxes(genv) if me.decls.empty?
|
|
684
|
+
genv.add_run(self)
|
|
627
685
|
end
|
|
628
686
|
|
|
629
687
|
attr_accessor :node
|
|
@@ -633,11 +691,8 @@ module TypeProf::Core
|
|
|
633
691
|
def destroy(genv)
|
|
634
692
|
me = genv.resolve_method(@cpath, @singleton, @new_mid)
|
|
635
693
|
me.remove_alias(self)
|
|
636
|
-
if me.decls.empty?
|
|
637
|
-
|
|
638
|
-
else
|
|
639
|
-
genv.add_run(self)
|
|
640
|
-
end
|
|
694
|
+
me.add_run_all_method_call_boxes(genv) if me.decls.empty?
|
|
695
|
+
genv.add_run(self)
|
|
641
696
|
super(genv)
|
|
642
697
|
end
|
|
643
698
|
|
|
@@ -654,7 +709,6 @@ module TypeProf::Core
|
|
|
654
709
|
@recv.add_edge(genv, self)
|
|
655
710
|
@mid = mid
|
|
656
711
|
@a_args = a_args.new_vertexes(genv, node)
|
|
657
|
-
@a_args.positionals.each {|arg| arg.add_edge(genv, self) }
|
|
658
712
|
@a_args.keywords.add_edge(genv, self) if @a_args.keywords
|
|
659
713
|
@a_args.block.add_edge(genv, self) if @a_args.block
|
|
660
714
|
@ret = Vertex.new(node)
|
|
@@ -742,6 +796,16 @@ module TypeProf::Core
|
|
|
742
796
|
alias_limit = 0
|
|
743
797
|
while ty
|
|
744
798
|
unless skip
|
|
799
|
+
# First check prepended modules
|
|
800
|
+
if !ty.is_a?(Type::Singleton)
|
|
801
|
+
if resolve_prepended_modules(genv, changes, base_ty_env, ty, mid) do |me, ty, mid|
|
|
802
|
+
yield me, ty, mid, orig_ty
|
|
803
|
+
end
|
|
804
|
+
break
|
|
805
|
+
end
|
|
806
|
+
end
|
|
807
|
+
|
|
808
|
+
# Then check the class/module itself
|
|
745
809
|
me = ty.mod.get_method(ty.is_a?(Type::Singleton), mid)
|
|
746
810
|
changes.add_depended_method_entity(me) if changes
|
|
747
811
|
if !me.aliases.empty?
|
|
@@ -760,6 +824,7 @@ module TypeProf::Core
|
|
|
760
824
|
if ty.is_a?(Type::Singleton)
|
|
761
825
|
# TODO: extended modules
|
|
762
826
|
else
|
|
827
|
+
# Finally check included modules
|
|
763
828
|
break if resolve_included_modules(genv, changes, base_ty_env, ty, mid) do |me, ty, mid|
|
|
764
829
|
yield me, ty, mid, orig_ty
|
|
765
830
|
end
|
|
@@ -772,6 +837,38 @@ module TypeProf::Core
|
|
|
772
837
|
end
|
|
773
838
|
end
|
|
774
839
|
|
|
840
|
+
def resolve_prepended_modules(genv, changes, base_ty_env, ty, mid, &blk)
|
|
841
|
+
found = false
|
|
842
|
+
|
|
843
|
+
alias_limit = 0
|
|
844
|
+
# Process prepended modules in reverse order (last prepended = first in ancestor chain)
|
|
845
|
+
ty.mod.prepended_modules.reverse_each do |prep_decl, prep_mod|
|
|
846
|
+
if prep_decl.is_a?(AST::SigPrependNode) && prep_mod.type_params
|
|
847
|
+
prep_ty = genv.get_instance_type(prep_mod, prep_decl.args, changes, base_ty_env, ty)
|
|
848
|
+
else
|
|
849
|
+
type_params = prep_mod.type_params.map {|ty_param| Source.new() } # TODO: better support
|
|
850
|
+
prep_ty = Type::Instance.new(genv, prep_mod, type_params)
|
|
851
|
+
end
|
|
852
|
+
|
|
853
|
+
me = prep_ty.mod.get_method(false, mid)
|
|
854
|
+
changes.add_depended_method_entity(me) if changes
|
|
855
|
+
if !me.aliases.empty?
|
|
856
|
+
mid = me.aliases.values.first
|
|
857
|
+
alias_limit += 1
|
|
858
|
+
redo if alias_limit < 5
|
|
859
|
+
end
|
|
860
|
+
if me.exist?
|
|
861
|
+
found = true
|
|
862
|
+
yield me, prep_ty, mid
|
|
863
|
+
else
|
|
864
|
+
found = resolve_prepended_modules(genv, changes, base_ty_env, prep_ty, mid, &blk)
|
|
865
|
+
end
|
|
866
|
+
break if found
|
|
867
|
+
end
|
|
868
|
+
|
|
869
|
+
found
|
|
870
|
+
end
|
|
871
|
+
|
|
775
872
|
def resolve_included_modules(genv, changes, base_ty_env, ty, mid, &blk)
|
|
776
873
|
found = false
|
|
777
874
|
|
|
@@ -988,4 +1085,24 @@ module TypeProf::Core
|
|
|
988
1085
|
end
|
|
989
1086
|
end
|
|
990
1087
|
end
|
|
1088
|
+
|
|
1089
|
+
class InstanceTypeBox < Box
|
|
1090
|
+
def initialize(node, genv, singleton_ty_vtx)
|
|
1091
|
+
super(node)
|
|
1092
|
+
@singleton_ty_vtx = singleton_ty_vtx
|
|
1093
|
+
@ret = Vertex.new(node)
|
|
1094
|
+
genv.add_run(self)
|
|
1095
|
+
end
|
|
1096
|
+
|
|
1097
|
+
attr_reader :ret
|
|
1098
|
+
|
|
1099
|
+
def run0(genv, changes)
|
|
1100
|
+
instance_tys = []
|
|
1101
|
+
@singleton_ty_vtx.each_type do |ty|
|
|
1102
|
+
instance_tys << ty.get_instance_type(genv)
|
|
1103
|
+
end
|
|
1104
|
+
source_vtx = Source.new(*instance_tys)
|
|
1105
|
+
changes.add_edge(genv, source_vtx, @ret)
|
|
1106
|
+
end
|
|
1107
|
+
end
|
|
991
1108
|
end
|