typeprof 0.3.0 → 0.4.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/Gemfile.lock +1 -1
- data/doc/demo.md +398 -0
- data/doc/doc.ja.md +4 -0
- data/doc/doc.md +4 -0
- data/lib/typeprof.rb +8 -0
- data/lib/typeprof/analyzer.rb +229 -245
- data/lib/typeprof/arguments.rb +397 -0
- data/lib/typeprof/block.rb +133 -0
- data/lib/typeprof/builtin.rb +14 -10
- data/lib/typeprof/container-type.rb +94 -17
- data/lib/typeprof/export.rb +185 -108
- data/lib/typeprof/import.rb +76 -54
- data/lib/typeprof/iseq.rb +27 -2
- data/lib/typeprof/method.rb +87 -73
- data/lib/typeprof/type.rb +125 -309
- data/lib/typeprof/version.rb +1 -1
- data/smoke/arguments2.rb +1 -1
- data/smoke/array-each3.rb +1 -4
- data/smoke/array12.rb +1 -1
- data/smoke/array6.rb +1 -0
- data/smoke/block-ambiguous.rb +36 -0
- data/smoke/block-args1-rest.rb +62 -0
- data/smoke/block-args1.rb +59 -0
- data/smoke/block-args2-rest.rb +62 -0
- data/smoke/block-args2.rb +59 -0
- data/smoke/block-args3-rest.rb +73 -0
- data/smoke/block-args3.rb +70 -0
- data/smoke/block-blockarg.rb +27 -0
- data/smoke/block-kwarg.rb +52 -0
- data/smoke/block11.rb +1 -1
- data/smoke/block14.rb +17 -0
- data/smoke/block4.rb +2 -2
- data/smoke/block5.rb +1 -0
- data/smoke/block6.rb +1 -1
- data/smoke/block7.rb +0 -2
- data/smoke/block8.rb +2 -2
- data/smoke/block9.rb +1 -1
- data/smoke/blown.rb +1 -1
- data/smoke/class-hierarchy.rb +54 -0
- data/smoke/class-hierarchy2.rb +27 -0
- data/smoke/constant1.rb +11 -6
- data/smoke/constant2.rb +2 -0
- data/smoke/cvar.rb +1 -0
- data/smoke/demo10.rb +1 -1
- data/smoke/demo8.rb +2 -2
- data/smoke/demo9.rb +1 -3
- data/smoke/flow7.rb +1 -7
- data/smoke/flow8.rb +13 -0
- data/smoke/instance_eval.rb +1 -1
- data/smoke/int_times.rb +1 -1
- data/smoke/multiple-superclass.rb +4 -0
- data/smoke/next2.rb +1 -1
- data/smoke/optional3.rb +10 -0
- data/smoke/proc4.rb +1 -1
- data/smoke/rbs-proc1.rb +9 -0
- data/smoke/rbs-proc1.rbs +3 -0
- data/smoke/rbs-proc2.rb +20 -0
- data/smoke/rbs-proc2.rbs +3 -0
- data/smoke/rbs-proc3.rb +13 -0
- data/smoke/rbs-proc3.rbs +4 -0
- data/smoke/rbs-record.rb +17 -0
- data/smoke/rbs-record.rbs +4 -0
- data/smoke/rbs-tyvar3.rb +25 -0
- data/smoke/rbs-tyvar3.rbs +4 -0
- data/smoke/rest2.rb +1 -1
- data/smoke/rest5.rb +1 -1
- data/smoke/return.rb +1 -1
- data/smoke/singleton_method.rb +3 -0
- data/smoke/struct.rb +4 -3
- data/smoke/struct3.rb +14 -0
- data/smoke/symbol-proc.rb +24 -0
- metadata +31 -3
- data/smoke/variadic1.rb.notyet +0 -5
data/lib/typeprof/analyzer.rb
CHANGED
|
@@ -182,22 +182,8 @@ module TypeProf
|
|
|
182
182
|
Env.new(@static_env, Utils.array_update(@locals, idx, ty), @stack, @type_params)
|
|
183
183
|
end
|
|
184
184
|
|
|
185
|
-
def
|
|
186
|
-
local_ty =
|
|
187
|
-
type_params = Utils::HashWrapper.new(@type_params.internal_hash.merge({ alloc_site => elems }))
|
|
188
|
-
nenv = Env.new(@static_env, @locals, @stack, type_params)
|
|
189
|
-
return nenv, local_ty
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
def deploy_array_type(alloc_site, elems, base_ty)
|
|
193
|
-
local_ty = Type::LocalArray.new(alloc_site, base_ty)
|
|
194
|
-
type_params = Utils::HashWrapper.new(@type_params.internal_hash.merge({ alloc_site => elems }))
|
|
195
|
-
nenv = Env.new(@static_env, @locals, @stack, type_params)
|
|
196
|
-
return nenv, local_ty
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
def deploy_hash_type(alloc_site, elems, base_ty)
|
|
200
|
-
local_ty = Type::LocalHash.new(alloc_site, base_ty)
|
|
185
|
+
def deploy_type(klass, alloc_site, elems, base_ty)
|
|
186
|
+
local_ty = klass.new(alloc_site, base_ty)
|
|
201
187
|
type_params = Utils::HashWrapper.new(@type_params.internal_hash.merge({ alloc_site => elems }))
|
|
202
188
|
nenv = Env.new(@static_env, @locals, @stack, type_params)
|
|
203
189
|
return nenv, local_ty
|
|
@@ -244,8 +230,11 @@ module TypeProf
|
|
|
244
230
|
|
|
245
231
|
@alloc_site_to_global_id = {}
|
|
246
232
|
|
|
247
|
-
@callsites, @return_envs
|
|
233
|
+
@callsites, @return_envs = {}, {}
|
|
248
234
|
@block_to_ctx = {}
|
|
235
|
+
@method_signatures = {}
|
|
236
|
+
@block_signatures = {}
|
|
237
|
+
@return_values = {}
|
|
249
238
|
@gvar_table = VarTable.new
|
|
250
239
|
|
|
251
240
|
@errors = []
|
|
@@ -288,6 +277,7 @@ module TypeProf
|
|
|
288
277
|
|
|
289
278
|
class ClassDef # or ModuleDef
|
|
290
279
|
def initialize(kind, name, superclass, absolute_path)
|
|
280
|
+
raise unless name.is_a?(Array)
|
|
291
281
|
@kind = kind
|
|
292
282
|
@superclass = superclass
|
|
293
283
|
@modules = { true => {}, false => {} }
|
|
@@ -297,9 +287,10 @@ module TypeProf
|
|
|
297
287
|
@ivars = VarTable.new
|
|
298
288
|
@cvars = VarTable.new
|
|
299
289
|
@absolute_path = absolute_path
|
|
290
|
+
@namespace = nil
|
|
300
291
|
end
|
|
301
292
|
|
|
302
|
-
attr_reader :kind, :modules, :
|
|
293
|
+
attr_reader :kind, :superclass, :modules, :consts, :methods, :ivars, :cvars, :absolute_path
|
|
303
294
|
attr_accessor :name, :klass_obj
|
|
304
295
|
|
|
305
296
|
def include_module(mod, absolute_path)
|
|
@@ -321,14 +312,15 @@ module TypeProf
|
|
|
321
312
|
end
|
|
322
313
|
|
|
323
314
|
def get_constant(name)
|
|
324
|
-
@consts[name]
|
|
315
|
+
ty, = @consts[name]
|
|
316
|
+
ty || Type.any # XXX: warn?
|
|
325
317
|
end
|
|
326
318
|
|
|
327
|
-
def add_constant(name, ty)
|
|
319
|
+
def add_constant(name, ty, absolute_path)
|
|
328
320
|
if @consts[name]
|
|
329
321
|
# XXX: warn!
|
|
330
322
|
end
|
|
331
|
-
@consts[name] = ty
|
|
323
|
+
@consts[name] = [ty, absolute_path]
|
|
332
324
|
end
|
|
333
325
|
|
|
334
326
|
def get_method(mid, singleton)
|
|
@@ -391,12 +383,12 @@ module TypeProf
|
|
|
391
383
|
end
|
|
392
384
|
end
|
|
393
385
|
|
|
386
|
+
def cbase_path(cbase)
|
|
387
|
+
cbase && cbase.idx != 1 ? @class_defs[cbase.idx].name : []
|
|
388
|
+
end
|
|
389
|
+
|
|
394
390
|
def new_class(cbase, name, type_params, superclass, absolute_path)
|
|
395
|
-
|
|
396
|
-
show_name = "#{ @class_defs[cbase.idx].name }::#{ name }"
|
|
397
|
-
else
|
|
398
|
-
show_name = name.to_s
|
|
399
|
-
end
|
|
391
|
+
show_name = cbase_path(cbase) + [name]
|
|
400
392
|
idx = @class_defs.size
|
|
401
393
|
if superclass
|
|
402
394
|
if superclass == :__root__
|
|
@@ -408,14 +400,14 @@ module TypeProf
|
|
|
408
400
|
klass = Type::Class.new(:class, idx, type_params, superclass, show_name)
|
|
409
401
|
@class_defs[idx].klass_obj = klass
|
|
410
402
|
cbase ||= klass # for bootstrap
|
|
411
|
-
add_constant(cbase, name, klass)
|
|
403
|
+
add_constant(cbase, name, klass, absolute_path)
|
|
412
404
|
return klass
|
|
413
405
|
else
|
|
414
406
|
# module
|
|
415
407
|
@class_defs[idx] = ClassDef.new(:module, show_name, nil, absolute_path)
|
|
416
408
|
mod = Type::Class.new(:module, idx, type_params, nil, show_name)
|
|
417
409
|
@class_defs[idx].klass_obj = mod
|
|
418
|
-
add_constant(cbase, name, mod)
|
|
410
|
+
add_constant(cbase, name, mod, absolute_path)
|
|
419
411
|
return mod
|
|
420
412
|
end
|
|
421
413
|
end
|
|
@@ -425,8 +417,8 @@ module TypeProf
|
|
|
425
417
|
|
|
426
418
|
idx = @class_defs.size
|
|
427
419
|
superclass = Type::Builtin[:struct]
|
|
428
|
-
@class_defs[idx] = ClassDef.new(:class, "(Struct)", superclass.idx, ep.ctx.iseq.absolute_path)
|
|
429
|
-
klass = Type::Class.new(:class, idx, [], superclass, "(Struct)")
|
|
420
|
+
@class_defs[idx] = ClassDef.new(:class, ["(Anonymous Struct)"], superclass.idx, ep.ctx.iseq.absolute_path)
|
|
421
|
+
klass = Type::Class.new(:class, idx, [], superclass, "(Anonymous Struct)")
|
|
430
422
|
@class_defs[idx].klass_obj = klass
|
|
431
423
|
|
|
432
424
|
@struct_defs[ep] = klass
|
|
@@ -434,11 +426,25 @@ module TypeProf
|
|
|
434
426
|
klass
|
|
435
427
|
end
|
|
436
428
|
|
|
429
|
+
attr_accessor :namespace
|
|
430
|
+
|
|
437
431
|
def get_class_name(klass)
|
|
438
432
|
if klass == Type.any
|
|
439
433
|
"???"
|
|
440
434
|
else
|
|
441
|
-
@class_defs[klass.idx].name
|
|
435
|
+
path = @class_defs[klass.idx].name
|
|
436
|
+
if @namespace
|
|
437
|
+
i = 0
|
|
438
|
+
i += 1 while @namespace[i] && @namespace[i] == path[i]
|
|
439
|
+
if path[i]
|
|
440
|
+
path[i..].join("::")
|
|
441
|
+
else
|
|
442
|
+
path.last.to_s
|
|
443
|
+
end
|
|
444
|
+
else
|
|
445
|
+
#"::" + path.join("::")
|
|
446
|
+
path.join("::")
|
|
447
|
+
end
|
|
442
448
|
end
|
|
443
449
|
end
|
|
444
450
|
|
|
@@ -488,11 +494,11 @@ module TypeProf
|
|
|
488
494
|
Type.any
|
|
489
495
|
end
|
|
490
496
|
|
|
491
|
-
def add_constant(klass, name, value)
|
|
497
|
+
def add_constant(klass, name, value, user_defined)
|
|
492
498
|
if klass == Type.any
|
|
493
499
|
self
|
|
494
500
|
else
|
|
495
|
-
@class_defs[klass.idx].add_constant(name, value)
|
|
501
|
+
@class_defs[klass.idx].add_constant(name, value, user_defined)
|
|
496
502
|
end
|
|
497
503
|
end
|
|
498
504
|
|
|
@@ -527,14 +533,6 @@ module TypeProf
|
|
|
527
533
|
add_method(klass, mid, true, ISeqMethodDef.new(iseq, cref))
|
|
528
534
|
end
|
|
529
535
|
|
|
530
|
-
def add_typed_method(recv_ty, mid, fargs, ret_ty)
|
|
531
|
-
add_method(recv_ty.klass, mid, false, TypedMethodDef.new([[fargs, ret_ty]]))
|
|
532
|
-
end
|
|
533
|
-
|
|
534
|
-
def add_singleton_typed_method(recv_ty, mid, fargs, ret_ty)
|
|
535
|
-
add_method(recv_ty.klass, mid, true, TypedMethodDef.new([[fargs, ret_ty]]))
|
|
536
|
-
end
|
|
537
|
-
|
|
538
536
|
def set_custom_method(klass, mid, impl)
|
|
539
537
|
set_method(klass, mid, false, CustomMethodDef.new(impl))
|
|
540
538
|
end
|
|
@@ -572,7 +570,7 @@ module TypeProf
|
|
|
572
570
|
@callsites[callee_ctx][caller_ep] = ctn
|
|
573
571
|
merge_return_env(caller_ep) {|env| env ? env.merge(caller_env) : caller_env }
|
|
574
572
|
|
|
575
|
-
ret_ty = @
|
|
573
|
+
ret_ty = @return_values[callee_ctx] ||= Type.bot
|
|
576
574
|
if ret_ty != Type.bot
|
|
577
575
|
@callsites[callee_ctx].each do |caller_ep, ctn|
|
|
578
576
|
ctn[ret_ty, caller_ep, @return_envs[caller_ep]]
|
|
@@ -580,11 +578,11 @@ module TypeProf
|
|
|
580
578
|
end
|
|
581
579
|
end
|
|
582
580
|
|
|
583
|
-
def
|
|
584
|
-
if @
|
|
585
|
-
@
|
|
581
|
+
def add_method_signature!(callee_ctx, msig)
|
|
582
|
+
if @method_signatures[callee_ctx]
|
|
583
|
+
@method_signatures[callee_ctx] = @method_signatures[callee_ctx].merge(msig)
|
|
586
584
|
else
|
|
587
|
-
@
|
|
585
|
+
@method_signatures[callee_ctx] = msig
|
|
588
586
|
end
|
|
589
587
|
end
|
|
590
588
|
|
|
@@ -592,9 +590,9 @@ module TypeProf
|
|
|
592
590
|
@return_envs[caller_ep] = yield @return_envs[caller_ep]
|
|
593
591
|
end
|
|
594
592
|
|
|
595
|
-
def
|
|
596
|
-
@
|
|
597
|
-
@
|
|
593
|
+
def add_return_value!(callee_ctx, ret_ty)
|
|
594
|
+
@return_values[callee_ctx] ||= Type.bot
|
|
595
|
+
@return_values[callee_ctx] = @return_values[callee_ctx].union(ret_ty)
|
|
598
596
|
|
|
599
597
|
@callsites[callee_ctx] ||= {}
|
|
600
598
|
@callsites[callee_ctx].each do |caller_ep, ctn|
|
|
@@ -602,19 +600,18 @@ module TypeProf
|
|
|
602
600
|
end
|
|
603
601
|
end
|
|
604
602
|
|
|
605
|
-
def
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
else
|
|
610
|
-
@yields[caller_ctx] = [aargs, Utils::MutableSet.new]
|
|
611
|
-
end
|
|
612
|
-
@yields[caller_ctx][1] << blk_ctx
|
|
603
|
+
def add_block_to_ctx!(block_body, ctx)
|
|
604
|
+
raise if !block_body.is_a?(Block)
|
|
605
|
+
@block_to_ctx[block_body] ||= Utils::MutableSet.new
|
|
606
|
+
@block_to_ctx[block_body] << ctx
|
|
613
607
|
end
|
|
614
608
|
|
|
615
|
-
def
|
|
616
|
-
@
|
|
617
|
-
|
|
609
|
+
def add_block_signature!(block_body, bsig)
|
|
610
|
+
if @block_signatures[block_body]
|
|
611
|
+
@block_signatures[block_body] = @block_signatures[block_body].merge(bsig)
|
|
612
|
+
else
|
|
613
|
+
@block_signatures[block_body] = bsig
|
|
614
|
+
end
|
|
618
615
|
end
|
|
619
616
|
|
|
620
617
|
class VarTable
|
|
@@ -736,7 +733,7 @@ module TypeProf
|
|
|
736
733
|
env.get_container_elem_types(id)
|
|
737
734
|
end
|
|
738
735
|
|
|
739
|
-
def update_container_elem_types(env, ep, id)
|
|
736
|
+
def update_container_elem_types(env, ep, id, base_type)
|
|
740
737
|
if ep.outer
|
|
741
738
|
tmp_ep = ep
|
|
742
739
|
tmp_ep = tmp_ep.outer while tmp_ep.outer
|
|
@@ -746,7 +743,7 @@ module TypeProf
|
|
|
746
743
|
menv = menv.update_container_elem_types(id, elems)
|
|
747
744
|
gid = @alloc_site_to_global_id[id]
|
|
748
745
|
if gid
|
|
749
|
-
ty = globalize_type(elems.to_local_type(id), env, ep)
|
|
746
|
+
ty = globalize_type(elems.to_local_type(id, base_type), env, ep)
|
|
750
747
|
add_ivar_write!(*gid, ty, ep)
|
|
751
748
|
end
|
|
752
749
|
menv
|
|
@@ -758,7 +755,7 @@ module TypeProf
|
|
|
758
755
|
env = env.update_container_elem_types(id, elems)
|
|
759
756
|
gid = @alloc_site_to_global_id[id]
|
|
760
757
|
if gid
|
|
761
|
-
ty = globalize_type(elems.to_local_type(id), env, ep)
|
|
758
|
+
ty = globalize_type(elems.to_local_type(id, base_type), env, ep)
|
|
762
759
|
add_ivar_write!(*gid, ty, ep)
|
|
763
760
|
end
|
|
764
761
|
env
|
|
@@ -770,7 +767,7 @@ module TypeProf
|
|
|
770
767
|
|
|
771
768
|
if elems
|
|
772
769
|
return elems[idx] || Type.nil if idx
|
|
773
|
-
return elems.
|
|
770
|
+
return elems.squash_or_any
|
|
774
771
|
else
|
|
775
772
|
Type.any
|
|
776
773
|
end
|
|
@@ -836,9 +833,10 @@ module TypeProf
|
|
|
836
833
|
add_iseq_method_call!(meth, ep.ctx)
|
|
837
834
|
|
|
838
835
|
when :block
|
|
839
|
-
epenvs = dummy_continuation
|
|
836
|
+
blk, epenvs = dummy_continuation
|
|
840
837
|
epenvs.each do |ep, env|
|
|
841
838
|
merge_env(ep, env)
|
|
839
|
+
add_block_to_ctx!(blk.block_body, ep.ctx)
|
|
842
840
|
end
|
|
843
841
|
end
|
|
844
842
|
end
|
|
@@ -856,12 +854,7 @@ module TypeProf
|
|
|
856
854
|
|
|
857
855
|
Reporters.show_gvars(self, @gvar_table, output)
|
|
858
856
|
|
|
859
|
-
|
|
860
|
-
# self, @include_relations, @ivar_table.write, @cvar_table.write, @class_defs
|
|
861
|
-
#).show
|
|
862
|
-
|
|
863
|
-
#return
|
|
864
|
-
RubySignatureExporter.new(self, @class_defs, @iseq_method_to_ctxs, @sig_fargs, @sig_ret, @yields).show(stat_eps, output)
|
|
857
|
+
RubySignatureExporter.new(self, @class_defs, @iseq_method_to_ctxs).show(stat_eps, output)
|
|
865
858
|
end
|
|
866
859
|
|
|
867
860
|
def globalize_type(ty, env, ep)
|
|
@@ -915,12 +908,12 @@ module TypeProf
|
|
|
915
908
|
@pending_execution[iseq] ||= [:method, [meth, ep, env]]
|
|
916
909
|
end
|
|
917
910
|
|
|
918
|
-
def pend_block_dummy_execution(iseq, nep, nenv)
|
|
919
|
-
@pending_execution[iseq] ||= [:block, {}]
|
|
920
|
-
if @pending_execution[iseq][1][nep]
|
|
921
|
-
@pending_execution[iseq][1][nep] = @pending_execution[iseq][1][nep].merge(nenv)
|
|
911
|
+
def pend_block_dummy_execution(blk, iseq, nep, nenv)
|
|
912
|
+
@pending_execution[iseq] ||= [:block, [blk, {}]]
|
|
913
|
+
if @pending_execution[iseq][1][1][nep]
|
|
914
|
+
@pending_execution[iseq][1][1][nep] = @pending_execution[iseq][1][1][nep].merge(nenv)
|
|
922
915
|
else
|
|
923
|
-
@pending_execution[iseq][1][nep] = nenv
|
|
916
|
+
@pending_execution[iseq][1][1][nep] = nenv
|
|
924
917
|
end
|
|
925
918
|
end
|
|
926
919
|
|
|
@@ -929,7 +922,7 @@ module TypeProf
|
|
|
929
922
|
alloc_site = AllocationSite.new(ep)
|
|
930
923
|
nenv, ty = localize_type(ty, env, ep, alloc_site)
|
|
931
924
|
case ty
|
|
932
|
-
when Type::LocalArray, Type::LocalHash
|
|
925
|
+
when Type::LocalCell, Type::LocalArray, Type::LocalHash
|
|
933
926
|
@alloc_site_to_global_id[ty.id] = [recv, var] # need overwrite check??
|
|
934
927
|
end
|
|
935
928
|
yield ty, nenv
|
|
@@ -954,7 +947,7 @@ module TypeProf
|
|
|
954
947
|
end
|
|
955
948
|
|
|
956
949
|
case insn
|
|
957
|
-
when :
|
|
950
|
+
when :_iseq_body_start
|
|
958
951
|
# XXX: reconstruct and record the method signature
|
|
959
952
|
iseq = ep.ctx.iseq
|
|
960
953
|
lead_num = iseq.fargs_format[:lead_num] || 0
|
|
@@ -1006,9 +999,15 @@ module TypeProf
|
|
|
1006
999
|
end
|
|
1007
1000
|
end
|
|
1008
1001
|
kw_rest_ty = globalize_type(env.locals[kw_rest], env, ep) if kw_rest
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1002
|
+
if block_start
|
|
1003
|
+
blk_ty = globalize_type(env.locals[block_start], env, ep)
|
|
1004
|
+
elsif iseq.type == :method
|
|
1005
|
+
blk_ty = env.static_env.blk_ty
|
|
1006
|
+
else
|
|
1007
|
+
blk_ty = Type.nil
|
|
1008
|
+
end
|
|
1009
|
+
msig = MethodSignature.new(lead_tys, opt_tys, rest_ty, post_tys, kw_tys, kw_rest_ty, blk_ty)
|
|
1010
|
+
add_method_signature!(ep.ctx, msig)
|
|
1012
1011
|
when :putspecialobject
|
|
1013
1012
|
kind, = operands
|
|
1014
1013
|
ty = case kind
|
|
@@ -1188,7 +1187,7 @@ module TypeProf
|
|
|
1188
1187
|
end
|
|
1189
1188
|
return
|
|
1190
1189
|
when :send
|
|
1191
|
-
env, recvs, mid, aargs = setup_actual_arguments(operands, ep, env)
|
|
1190
|
+
env, recvs, mid, aargs = setup_actual_arguments(:method, operands, ep, env)
|
|
1192
1191
|
recvs = Type.any if recvs == Type.bot
|
|
1193
1192
|
recvs.each_child do |recv|
|
|
1194
1193
|
do_send(recv, mid, aargs, ep, env) do |ret_ty, ep, env|
|
|
@@ -1200,7 +1199,7 @@ module TypeProf
|
|
|
1200
1199
|
return
|
|
1201
1200
|
when :send_branch
|
|
1202
1201
|
getlocal_operands, send_operands, branch_operands = operands
|
|
1203
|
-
env, recvs, mid, aargs = setup_actual_arguments(send_operands, ep, env)
|
|
1202
|
+
env, recvs, mid, aargs = setup_actual_arguments(:method, send_operands, ep, env)
|
|
1204
1203
|
recvs = Type.any if recvs == Type.bot
|
|
1205
1204
|
recvs.each_child do |recv|
|
|
1206
1205
|
do_send(recv, mid, aargs, ep, env) do |ret_ty, ep, env|
|
|
@@ -1227,11 +1226,7 @@ module TypeProf
|
|
|
1227
1226
|
end
|
|
1228
1227
|
return
|
|
1229
1228
|
when :invokeblock
|
|
1230
|
-
|
|
1231
|
-
opt, = operands
|
|
1232
|
-
_flags = opt[:flag]
|
|
1233
|
-
orig_argc = opt[:orig_argc]
|
|
1234
|
-
env, aargs = env.pop(orig_argc)
|
|
1229
|
+
env, recvs, mid, aargs = setup_actual_arguments(:block, operands, ep, env)
|
|
1235
1230
|
blk = env.static_env.blk_ty
|
|
1236
1231
|
case
|
|
1237
1232
|
when blk == Type.nil
|
|
@@ -1240,10 +1235,7 @@ module TypeProf
|
|
|
1240
1235
|
#warn(ep, "block is any")
|
|
1241
1236
|
env = env.push(Type.any)
|
|
1242
1237
|
else # Proc
|
|
1243
|
-
|
|
1244
|
-
#
|
|
1245
|
-
aargs = ActualArguments.new(aargs, nil, {}, blk_nil)
|
|
1246
|
-
do_invoke_block(true, env.static_env.blk_ty, aargs, ep, env) do |ret_ty, ep, env|
|
|
1238
|
+
do_invoke_block(blk, aargs, ep, env) do |ret_ty, ep, env|
|
|
1247
1239
|
nenv, ret_ty, = localize_type(ret_ty, env, ep)
|
|
1248
1240
|
nenv = nenv.push(ret_ty)
|
|
1249
1241
|
merge_env(ep.next, nenv)
|
|
@@ -1251,7 +1243,7 @@ module TypeProf
|
|
|
1251
1243
|
return
|
|
1252
1244
|
end
|
|
1253
1245
|
when :invokesuper
|
|
1254
|
-
env, recv, _, aargs = setup_actual_arguments(operands, ep, env)
|
|
1246
|
+
env, recv, _, aargs = setup_actual_arguments(:method, operands, ep, env)
|
|
1255
1247
|
|
|
1256
1248
|
env, recv = localize_type(env.static_env.recv_ty, env, ep)
|
|
1257
1249
|
mid = ep.ctx.mid
|
|
@@ -1284,7 +1276,7 @@ module TypeProf
|
|
|
1284
1276
|
end
|
|
1285
1277
|
env, (ty,) = env.pop(1)
|
|
1286
1278
|
ty = globalize_type(ty, env, ep)
|
|
1287
|
-
|
|
1279
|
+
add_return_value!(ep.ctx, ty)
|
|
1288
1280
|
return
|
|
1289
1281
|
when :throw
|
|
1290
1282
|
throwtype, = operands
|
|
@@ -1298,7 +1290,7 @@ module TypeProf
|
|
|
1298
1290
|
ty = globalize_type(ty, env, ep)
|
|
1299
1291
|
tmp_ep = ep
|
|
1300
1292
|
tmp_ep = tmp_ep.outer while tmp_ep.outer
|
|
1301
|
-
|
|
1293
|
+
add_return_value!(tmp_ep.ctx, ty)
|
|
1302
1294
|
return
|
|
1303
1295
|
when :break
|
|
1304
1296
|
tmp_ep = ep
|
|
@@ -1444,8 +1436,37 @@ module TypeProf
|
|
|
1444
1436
|
flow_env = env.local_update(-var_idx+2, ret_ty)
|
|
1445
1437
|
case ret_ty
|
|
1446
1438
|
when Type.any
|
|
1447
|
-
merge_env(ep_then,
|
|
1448
|
-
merge_env(ep_else,
|
|
1439
|
+
merge_env(ep_then, flow_env)
|
|
1440
|
+
merge_env(ep_else, flow_env)
|
|
1441
|
+
when Type::Instance.new(Type::Builtin[:false]), Type.nil
|
|
1442
|
+
merge_env(branchtype == :if ? ep_then : ep_else, flow_env)
|
|
1443
|
+
else
|
|
1444
|
+
merge_env(branchtype == :if ? ep_else : ep_then, flow_env)
|
|
1445
|
+
end
|
|
1446
|
+
end
|
|
1447
|
+
return
|
|
1448
|
+
when :getlocal_dup_branch
|
|
1449
|
+
getlocal_operands, _dup_operands, branch_operands = operands
|
|
1450
|
+
var_idx, _scope_idx, _escaped = getlocal_operands
|
|
1451
|
+
ret_ty = env.get_local(-var_idx+2)
|
|
1452
|
+
unless ret_ty
|
|
1453
|
+
p env.locals
|
|
1454
|
+
raise
|
|
1455
|
+
end
|
|
1456
|
+
|
|
1457
|
+
branchtype, target, = branch_operands
|
|
1458
|
+
# branchtype: :if or :unless or :nil
|
|
1459
|
+
ep_then = ep.next
|
|
1460
|
+
ep_else = ep.jump(target)
|
|
1461
|
+
|
|
1462
|
+
var_idx, _scope_idx, _escaped = getlocal_operands
|
|
1463
|
+
|
|
1464
|
+
ret_ty.each_child do |ret_ty|
|
|
1465
|
+
flow_env = env.local_update(-var_idx+2, ret_ty).push(ret_ty)
|
|
1466
|
+
case ret_ty
|
|
1467
|
+
when Type.any
|
|
1468
|
+
merge_env(ep_then, flow_env)
|
|
1469
|
+
merge_env(ep_else, flow_env)
|
|
1449
1470
|
when Type::Instance.new(Type::Builtin[:false]), Type.nil
|
|
1450
1471
|
merge_env(branchtype == :if ? ep_then : ep_else, flow_env)
|
|
1451
1472
|
else
|
|
@@ -1469,6 +1490,10 @@ module TypeProf
|
|
|
1469
1490
|
|
|
1470
1491
|
ret_ty.each_child do |ret_ty|
|
|
1471
1492
|
flow_env = env.local_update(-var_idx+2, ret_ty)
|
|
1493
|
+
ret_ty = ret_ty.base_type if ret_ty.is_a?(Type::Symbol)
|
|
1494
|
+
ret_ty = ret_ty.base_type if ret_ty.is_a?(Type::LocalCell)
|
|
1495
|
+
ret_ty = ret_ty.base_type if ret_ty.is_a?(Type::LocalArray)
|
|
1496
|
+
ret_ty = ret_ty.base_type if ret_ty.is_a?(Type::LocalHash)
|
|
1472
1497
|
if ret_ty.is_a?(Type::Instance)
|
|
1473
1498
|
if ret_ty.klass == pattern_ty # XXX: inheritance
|
|
1474
1499
|
merge_env(branchtype == :if ? ep_else : ep_then, flow_env)
|
|
@@ -1476,8 +1501,8 @@ module TypeProf
|
|
|
1476
1501
|
merge_env(branchtype == :if ? ep_then : ep_else, flow_env)
|
|
1477
1502
|
end
|
|
1478
1503
|
else
|
|
1479
|
-
merge_env(ep_then,
|
|
1480
|
-
merge_env(ep_else,
|
|
1504
|
+
merge_env(ep_then, flow_env)
|
|
1505
|
+
merge_env(ep_else, flow_env)
|
|
1481
1506
|
end
|
|
1482
1507
|
end
|
|
1483
1508
|
return
|
|
@@ -1518,10 +1543,10 @@ module TypeProf
|
|
|
1518
1543
|
end
|
|
1519
1544
|
ty.each_child do |ty|
|
|
1520
1545
|
if ty.is_a?(Type::Class) && ty.superclass == Type::Builtin[:struct]
|
|
1521
|
-
@class_defs[ty.idx].name = name
|
|
1546
|
+
@class_defs[ty.idx].name = cbase_path(cbase) + [name]
|
|
1522
1547
|
end
|
|
1523
1548
|
end
|
|
1524
|
-
add_constant(cbase, name, globalize_type(ty, env, ep))
|
|
1549
|
+
add_constant(cbase, name, globalize_type(ty, env, ep), ep.ctx.iseq.absolute_path)
|
|
1525
1550
|
|
|
1526
1551
|
when :getspecial
|
|
1527
1552
|
key, type = operands
|
|
@@ -1550,6 +1575,28 @@ module TypeProf
|
|
|
1550
1575
|
when :dup
|
|
1551
1576
|
env, (ty,) = env.pop(1)
|
|
1552
1577
|
env = env.push(ty).push(ty)
|
|
1578
|
+
when :dup_branch
|
|
1579
|
+
_dup_operands, branch_operands = operands
|
|
1580
|
+
env, (ty,) = env.pop(1)
|
|
1581
|
+
|
|
1582
|
+
branchtype, target, = branch_operands
|
|
1583
|
+
# branchtype: :if or :unless or :nil
|
|
1584
|
+
ep_then = ep.next
|
|
1585
|
+
ep_else = ep.jump(target)
|
|
1586
|
+
|
|
1587
|
+
ty.each_child do |ty|
|
|
1588
|
+
flow_env = env.push(ty)
|
|
1589
|
+
case ty
|
|
1590
|
+
when Type.any
|
|
1591
|
+
merge_env(ep_then, flow_env)
|
|
1592
|
+
merge_env(ep_else, flow_env)
|
|
1593
|
+
when Type::Instance.new(Type::Builtin[:false]), Type.nil
|
|
1594
|
+
merge_env(branchtype == :if ? ep_then : ep_else, flow_env)
|
|
1595
|
+
else
|
|
1596
|
+
merge_env(branchtype == :if ? ep_else : ep_then, flow_env)
|
|
1597
|
+
end
|
|
1598
|
+
end
|
|
1599
|
+
return
|
|
1553
1600
|
when :duphash
|
|
1554
1601
|
raw_hash, = operands
|
|
1555
1602
|
ty = Type.guess_literal_type(raw_hash)
|
|
@@ -1639,11 +1686,11 @@ module TypeProf
|
|
|
1639
1686
|
if ary2.is_a?(Type::LocalArray)
|
|
1640
1687
|
elems2 = get_container_elem_types(env, ep, ary2.id)
|
|
1641
1688
|
elems = Type::Array::Elements.new([], elems1.squash.union(elems2.squash))
|
|
1642
|
-
env = update_container_elem_types(env, ep, ary1.id) { elems }
|
|
1689
|
+
env = update_container_elem_types(env, ep, ary1.id, ary1.base_type) { elems }
|
|
1643
1690
|
env = env.push(ary1)
|
|
1644
1691
|
else
|
|
1645
1692
|
elems = Type::Array::Elements.new([], Type.any)
|
|
1646
|
-
env = update_container_elem_types(env, ep, ary1.id) { elems }
|
|
1693
|
+
env = update_container_elem_types(env, ep, ary1.id, ary1.base_type) { elems }
|
|
1647
1694
|
env = env.push(ary1)
|
|
1648
1695
|
end
|
|
1649
1696
|
else
|
|
@@ -1714,13 +1761,13 @@ module TypeProf
|
|
|
1714
1761
|
merge_env(ep.next, env)
|
|
1715
1762
|
end
|
|
1716
1763
|
|
|
1717
|
-
private def setup_actual_arguments(operands, ep, env)
|
|
1764
|
+
private def setup_actual_arguments(kind, operands, ep, env)
|
|
1718
1765
|
opt, blk_iseq = operands
|
|
1719
1766
|
flags = opt[:flag]
|
|
1720
1767
|
mid = opt[:mid]
|
|
1721
1768
|
kw_arg = opt[:kw_arg]
|
|
1722
1769
|
argc = opt[:orig_argc]
|
|
1723
|
-
argc += 1 # receiver
|
|
1770
|
+
argc += 1 if kind == :method # for the receiver
|
|
1724
1771
|
argc += kw_arg.size if kw_arg
|
|
1725
1772
|
|
|
1726
1773
|
flag_args_splat = flags[ 0] != 0
|
|
@@ -1735,29 +1782,36 @@ module TypeProf
|
|
|
1735
1782
|
_flag_super = flags[ 9] != 0
|
|
1736
1783
|
_flag_zsuper = flags[10] != 0
|
|
1737
1784
|
|
|
1785
|
+
argc += 1 if flag_args_blockarg
|
|
1786
|
+
|
|
1787
|
+
env, aargs = env.pop(argc)
|
|
1788
|
+
|
|
1789
|
+
recv = aargs.shift if kind == :method
|
|
1790
|
+
|
|
1738
1791
|
if flag_args_blockarg
|
|
1739
|
-
|
|
1740
|
-
|
|
1792
|
+
blk_ty = aargs.pop
|
|
1793
|
+
elsif blk_iseq
|
|
1794
|
+
blk_ty = Type::Proc.new(ISeqBlock.new(blk_iseq, ep), Type::Instance.new(Type::Builtin[:proc]))
|
|
1741
1795
|
else
|
|
1742
|
-
|
|
1743
|
-
if blk_iseq
|
|
1744
|
-
# check
|
|
1745
|
-
blk_ty = Type::ISeqProc.new(blk_iseq, ep, Type::Instance.new(Type::Builtin[:proc]))
|
|
1746
|
-
else
|
|
1747
|
-
blk_ty = Type.nil
|
|
1748
|
-
end
|
|
1796
|
+
blk_ty = Type.nil
|
|
1749
1797
|
end
|
|
1750
1798
|
|
|
1799
|
+
new_blk_ty = Type.bot
|
|
1751
1800
|
blk_ty.each_child do |blk_ty|
|
|
1752
1801
|
case blk_ty
|
|
1753
1802
|
when Type.nil
|
|
1754
1803
|
when Type.any
|
|
1755
|
-
when Type::
|
|
1804
|
+
when Type::Proc
|
|
1805
|
+
when Type::Symbol
|
|
1806
|
+
blk_ty = Type::Proc.new(SymbolBlock.new(blk_ty.sym), Type::Instance.new(Type::Builtin[:proc]))
|
|
1756
1807
|
else
|
|
1808
|
+
# XXX: attempt to call to_proc
|
|
1757
1809
|
error(ep, "wrong argument type #{ blk_ty.screen_name(self) } (expected Proc)")
|
|
1758
1810
|
blk_ty = Type.any
|
|
1759
1811
|
end
|
|
1812
|
+
new_blk_ty = new_blk_ty.union(blk_ty)
|
|
1760
1813
|
end
|
|
1814
|
+
blk_ty = new_blk_ty
|
|
1761
1815
|
|
|
1762
1816
|
if flag_args_splat
|
|
1763
1817
|
# assert !flag_args_kwarg
|
|
@@ -1841,7 +1895,7 @@ module TypeProf
|
|
|
1841
1895
|
nlocals = [Type.any] * blk_iseq.locals.size
|
|
1842
1896
|
nsenv = StaticEnv.new(env.static_env.recv_ty, Type.any, env.static_env.mod_func)
|
|
1843
1897
|
nenv = Env.new(nsenv, nlocals, [], nil)
|
|
1844
|
-
pend_block_dummy_execution(blk_iseq, nep, nenv)
|
|
1898
|
+
pend_block_dummy_execution(blk_ty, blk_iseq, nep, nenv)
|
|
1845
1899
|
merge_return_env(ep) {|tenv| tenv ? tenv.merge(env) : env }
|
|
1846
1900
|
end
|
|
1847
1901
|
|
|
@@ -1866,153 +1920,83 @@ module TypeProf
|
|
|
1866
1920
|
end
|
|
1867
1921
|
end
|
|
1868
1922
|
|
|
1869
|
-
def do_invoke_block(
|
|
1923
|
+
def do_invoke_block(blk, aargs, ep, env, replace_recv_ty: nil, &ctn)
|
|
1870
1924
|
blk.each_child do |blk|
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
next
|
|
1874
|
-
end
|
|
1875
|
-
blk_iseq = blk.iseq
|
|
1876
|
-
blk_ep = blk.ep
|
|
1877
|
-
blk_env = @return_envs[blk_ep]
|
|
1878
|
-
blk_env = blk_env.replace_recv_ty(replace_recv_ty) if replace_recv_ty
|
|
1879
|
-
arg_blk = aargs.blk_ty
|
|
1880
|
-
aargs_ = aargs.lead_tys.map {|aarg| globalize_type(aarg, env, ep) }
|
|
1881
|
-
# XXX: aargs.opt_tys and aargs.kw_tys
|
|
1882
|
-
argc = blk_iseq.fargs_format[:lead_num] || 0
|
|
1883
|
-
# actual argc == 1, not array, formal argc == 1: yield 42 => do |x| : x=42
|
|
1884
|
-
# actual argc == 1, array, formal argc == 1: yield [42,43,44] => do |x| : x=[42,43,44]
|
|
1885
|
-
# actual argc >= 2, formal argc == 1: yield 42,43,44 => do |x| : x=42
|
|
1886
|
-
# actual argc == 1, not array, formal argc >= 2: yield 42 => do |x,y| : x,y=42,nil
|
|
1887
|
-
# actual argc == 1, array, formal argc >= 2: yield [42,43,44] => do |x,y| : x,y=42,43
|
|
1888
|
-
# actual argc >= 2, formal argc >= 2: yield 42,43,44 => do |x,y| : x,y=42,43
|
|
1889
|
-
if aargs_.size >= 2 || argc == 0
|
|
1890
|
-
aargs_.pop while argc < aargs_.size
|
|
1891
|
-
aargs_ << Type.nil while argc > aargs_.size
|
|
1925
|
+
if blk.is_a?(Type::Proc)
|
|
1926
|
+
blk.block_body.do_call(aargs, ep, env, self, replace_recv_ty: replace_recv_ty, &ctn)
|
|
1892
1927
|
else
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
aargs_ = [aarg_ty || Type.nil]
|
|
1896
|
-
else # actual argc == 1 && formal argc >= 2
|
|
1897
|
-
ary_elems = nil
|
|
1898
|
-
any_ty = nil
|
|
1899
|
-
case aarg_ty
|
|
1900
|
-
when Type::Union
|
|
1901
|
-
ary_elems = nil
|
|
1902
|
-
other_elems = nil
|
|
1903
|
-
aarg_ty.elems&.each do |(container_kind, base_type), elems|
|
|
1904
|
-
if container_kind == Type::Array
|
|
1905
|
-
ary_elems = ary_elems ? ary_elems.union(elems) : elems
|
|
1906
|
-
else
|
|
1907
|
-
other_elems = other_elems ? other_elems.union(elems) : elems
|
|
1908
|
-
end
|
|
1909
|
-
end
|
|
1910
|
-
aarg_ty = Type::Union.new(aarg_ty.types, other_elems)
|
|
1911
|
-
any_ty = Type.any if aarg_ty.types.include?(Type.any)
|
|
1912
|
-
when Type::Array
|
|
1913
|
-
ary_elems = aarg_ty.elems
|
|
1914
|
-
aarg_ty = nil
|
|
1915
|
-
when Type::Any
|
|
1916
|
-
any_ty = Type.any
|
|
1917
|
-
end
|
|
1918
|
-
aargs_ = [Type.bot] * argc
|
|
1919
|
-
aargs_[0] = aargs_[0].union(aarg_ty) if aarg_ty
|
|
1920
|
-
argc.times do |i|
|
|
1921
|
-
ty = aargs_[i]
|
|
1922
|
-
ty = ty.union(ary_elems[i]) if ary_elems
|
|
1923
|
-
ty = ty.union(Type.any) if any_ty
|
|
1924
|
-
ty = ty.union(Type.nil) if i >= 1 && aarg_ty
|
|
1925
|
-
aargs_[i] = ty
|
|
1926
|
-
end
|
|
1927
|
-
end
|
|
1928
|
+
warn(ep, "non-proc is passed as a block")
|
|
1929
|
+
ctn[Type.any, ep, env]
|
|
1928
1930
|
end
|
|
1929
|
-
locals = [Type.nil] * blk_iseq.locals.size
|
|
1930
|
-
locals[blk_iseq.fargs_format[:block_start]] = arg_blk if blk_iseq.fargs_format[:block_start]
|
|
1931
|
-
env_blk = blk_env.static_env.blk_ty
|
|
1932
|
-
nfargs = FormalArguments.new(aargs_, [], nil, [], nil, nil, env_blk)
|
|
1933
|
-
nctx = Context.new(blk_iseq, blk_ep.ctx.cref, nil)
|
|
1934
|
-
nep = ExecutionPoint.new(nctx, 0, blk_ep)
|
|
1935
|
-
nenv = Env.new(blk_env.static_env, locals, [], nil)
|
|
1936
|
-
alloc_site = AllocationSite.new(nep)
|
|
1937
|
-
aargs_.each_with_index do |ty, i|
|
|
1938
|
-
alloc_site2 = alloc_site.add_id(i)
|
|
1939
|
-
nenv, ty = localize_type(ty, nenv, nep, alloc_site2) # Use Scratch#localize_type?
|
|
1940
|
-
nenv = nenv.local_update(i, ty)
|
|
1941
|
-
end
|
|
1942
|
-
|
|
1943
|
-
merge_env(nep, nenv)
|
|
1944
|
-
|
|
1945
|
-
# caution: given_block flag is not complete
|
|
1946
|
-
#
|
|
1947
|
-
# def foo
|
|
1948
|
-
# bar do |&blk|
|
|
1949
|
-
# yield
|
|
1950
|
-
# blk.call
|
|
1951
|
-
# end
|
|
1952
|
-
# end
|
|
1953
|
-
#
|
|
1954
|
-
# yield and blk.call call different blocks.
|
|
1955
|
-
# So, a context can have two blocks.
|
|
1956
|
-
# given_block is calculated by comparing "context's block (yield target)" and "blk", but it is not a correct result
|
|
1957
|
-
|
|
1958
|
-
add_yield!(ep.ctx, globalize_type(aargs, env, ep), nep.ctx) if given_block
|
|
1959
|
-
add_block_to_ctx!(blk, nep.ctx)
|
|
1960
|
-
add_callsite!(nep.ctx, ep, env, &ctn)
|
|
1961
|
-
add_signature!(nep.ctx, nfargs)
|
|
1962
1931
|
end
|
|
1963
1932
|
end
|
|
1964
1933
|
|
|
1965
|
-
def
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1934
|
+
def show_block_signature(blks)
|
|
1935
|
+
bsig = nil
|
|
1936
|
+
ret_ty = Type.bot
|
|
1937
|
+
|
|
1938
|
+
blks.each do |blk|
|
|
1939
|
+
blk.each_child_global do |blk|
|
|
1940
|
+
bsig0 = @block_signatures[blk.block_body]
|
|
1941
|
+
if bsig0
|
|
1942
|
+
if bsig
|
|
1943
|
+
bsig = bsig.merge(bsig0)
|
|
1944
|
+
else
|
|
1945
|
+
bsig = bsig0
|
|
1946
|
+
end
|
|
1947
|
+
end
|
|
1948
|
+
|
|
1949
|
+
@block_to_ctx[blk.block_body].each do |blk_ctx|
|
|
1950
|
+
ret_ty = ret_ty.union(@return_values[blk_ctx]) if @return_values[blk_ctx]
|
|
1971
1951
|
end
|
|
1972
|
-
else
|
|
1973
|
-
# uncalled proc? dummy execution doesn't work?
|
|
1974
|
-
#p blk
|
|
1975
1952
|
end
|
|
1976
1953
|
end
|
|
1977
|
-
|
|
1954
|
+
|
|
1955
|
+
bsig ||= BlockSignature.new([], [], nil, Type.nil)
|
|
1956
|
+
|
|
1957
|
+
bsig = bsig.screen_name(self)#, block: true)
|
|
1958
|
+
ret_ty = ret_ty.screen_name(self)
|
|
1959
|
+
ret_ty = (ret_ty.include?("|") ? "(#{ ret_ty })" : ret_ty) # XXX?
|
|
1960
|
+
|
|
1961
|
+
bsig = bsig + " " if bsig != ""
|
|
1962
|
+
"{ #{ bsig }-> #{ ret_ty } }"
|
|
1978
1963
|
end
|
|
1979
1964
|
|
|
1980
|
-
def
|
|
1981
|
-
|
|
1982
|
-
blk_ctxs.each do |blk_ctx, farg_tys|
|
|
1983
|
-
if all_farg_tys
|
|
1984
|
-
all_farg_tys = all_farg_tys.merge(farg_tys)
|
|
1985
|
-
else
|
|
1986
|
-
all_farg_tys = farg_tys
|
|
1987
|
-
end
|
|
1965
|
+
def show_proc_signature(blks)
|
|
1966
|
+
farg_tys, ret_ty = nil, Type.bot
|
|
1988
1967
|
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1968
|
+
blks.each do |blk|
|
|
1969
|
+
blk.each_child_global do |blk|
|
|
1970
|
+
next if blk.block_body.is_a?(TypedBlock) # XXX: Support TypedBlock
|
|
1971
|
+
next unless @block_to_ctx[blk.block_body] # this occurs when screen_name is called before type-profiling finished (e.g., error message)
|
|
1972
|
+
@block_to_ctx[blk.block_body].each do |blk_ctx|
|
|
1973
|
+
if farg_tys
|
|
1974
|
+
farg_tys = farg_tys.merge(@method_signatures[blk_ctx])
|
|
1975
|
+
else
|
|
1976
|
+
farg_tys = @method_signatures[blk_ctx]
|
|
1977
|
+
end
|
|
1978
|
+
|
|
1979
|
+
ret_ty = ret_ty.union(@return_values[blk_ctx]) if @return_values[blk_ctx]
|
|
1980
|
+
end
|
|
1993
1981
|
end
|
|
1994
1982
|
end
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1983
|
+
|
|
1984
|
+
farg_tys = farg_tys ? farg_tys.screen_name(self) : "(unknown)"
|
|
1985
|
+
ret_ty = ret_ty.screen_name(self)
|
|
1986
|
+
ret_ty = (ret_ty.include?("|") ? "(#{ ret_ty })" : ret_ty) # XXX?
|
|
1987
|
+
|
|
1988
|
+
farg_tys = farg_tys + " " if farg_tys != ""
|
|
1989
|
+
"^#{ farg_tys }-> #{ ret_ty }"
|
|
1998
1990
|
end
|
|
1999
1991
|
|
|
2000
|
-
def
|
|
1992
|
+
def show_method_signature(ctx)
|
|
1993
|
+
farg_tys = @method_signatures[ctx]
|
|
1994
|
+
ret_ty = @return_values[ctx] || Type.bot
|
|
1995
|
+
|
|
2001
1996
|
farg_tys = farg_tys.screen_name(self)
|
|
2002
1997
|
ret_ty = ret_ty.screen_name(self)
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
aargs, blk_ctxs = yield_data
|
|
2006
|
-
all_blk_ret_ty = Type.bot
|
|
2007
|
-
blk_ctxs.each do |blk_ctx|
|
|
2008
|
-
all_blk_ret_ty = all_blk_ret_ty.union(@sig_ret[blk_ctx])
|
|
2009
|
-
end
|
|
2010
|
-
all_blk_ret_ty = all_blk_ret_ty.screen_name(self)
|
|
2011
|
-
all_blk_ret_ty = all_blk_ret_ty.include?("|") ? "(#{ all_blk_ret_ty })" : all_blk_ret_ty
|
|
2012
|
-
s << "{ #{ aargs.screen_name(self) } -> #{ all_blk_ret_ty } } " if aargs
|
|
2013
|
-
end
|
|
2014
|
-
s << "-> "
|
|
2015
|
-
s << (ret_ty.include?("|") ? "(#{ ret_ty })" : ret_ty)
|
|
1998
|
+
ret_ty = (ret_ty.include?("|") ? "(#{ ret_ty })" : ret_ty) # XXX?
|
|
1999
|
+
"#{ (farg_tys.empty? ? "" : "#{ farg_tys } ") }-> #{ ret_ty }"
|
|
2016
2000
|
end
|
|
2017
2001
|
end
|
|
2018
2002
|
end
|