typeprof 0.14.0 → 0.15.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +10 -10
- data/lib/typeprof/analyzer.rb +154 -85
- data/lib/typeprof/builtin.rb +22 -12
- data/lib/typeprof/cli.rb +1 -0
- data/lib/typeprof/config.rb +2 -1
- data/lib/typeprof/export.rb +9 -5
- data/lib/typeprof/import.rb +55 -21
- data/lib/typeprof/iseq.rb +307 -202
- data/lib/typeprof/method.rb +2 -2
- data/lib/typeprof/type.rb +97 -47
- data/lib/typeprof/version.rb +1 -1
- data/smoke/alias2.rb +1 -1
- data/smoke/array3.rb +1 -1
- data/smoke/attr-module.rb +1 -4
- data/smoke/attr-vis.rb +1 -1
- data/smoke/attr.rb +1 -1
- data/smoke/break2.rb +1 -1
- data/smoke/gvar2.rb +0 -3
- data/smoke/huge_union.rb +86 -0
- data/smoke/identifier_keywords.rb +17 -0
- data/smoke/initialize.rb +1 -1
- data/smoke/ivar2.rb +1 -1
- data/smoke/ivar3.rb +1 -1
- data/smoke/kwrest.rb +2 -2
- data/smoke/kwrest.rbs +1 -1
- data/smoke/method_missing.rb +1 -1
- data/smoke/next2.rb +1 -1
- data/smoke/noname.rb +9 -0
- data/smoke/or_raise.rb +18 -0
- data/smoke/pattern-match1.rb +1 -6
- data/smoke/proc6.rb +13 -0
- data/smoke/proc7.rb +32 -0
- data/smoke/rbs-tyvar4.rb +1 -1
- data/smoke/rbs-vars.rb +0 -3
- data/smoke/require1.rb +13 -0
- data/smoke/require2.rb +13 -0
- data/smoke/struct5.rb +1 -1
- data/smoke/struct6.rb +1 -1
- data/smoke/struct7.rb +1 -1
- data/smoke/super3.rb +1 -1
- data/smoke/symbol-proc-attr.rb +1 -1
- data/smoke/symbol-proc-attr2.rb +1 -1
- data/testbed/ao.rb +1 -1
- data/typeprof.gemspec +1 -1
- metadata +12 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c31fc03c67fa15924e901b70890318e2391fa58cfaf897e51ff6a00d673d792a
|
4
|
+
data.tar.gz: c6ce703ec1c5f8a41d04603162746adb8a9416ccf29abc8ef1441cf83a3b41e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 790815f2528442ae742df0c3576a97ff6d2c856db374f2c8a63bb965dd6c715b6fa686d84b1fd56683e938e9c8e4014e9e86b53bb34ca4e9975b93bb5e5188df
|
7
|
+
data.tar.gz: ecc1433a74aebbe31c267c4697d71389a841cd66d74b251d1cc2d22bbeca228f141a8861ecbeebee3b16d54a8397f41eeab4f1f25ebac42103aee5e1146c9fe6
|
data/Gemfile.lock
CHANGED
@@ -1,25 +1,25 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
typeprof (0.
|
5
|
-
rbs (>= 1.
|
4
|
+
typeprof (0.15.1)
|
5
|
+
rbs (>= 1.3.1)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
10
|
coverage-helpers (1.0.0)
|
11
|
-
docile (1.
|
12
|
-
power_assert (
|
11
|
+
docile (1.4.0)
|
12
|
+
power_assert (2.0.0)
|
13
13
|
rake (13.0.1)
|
14
|
-
rbs (1.
|
15
|
-
simplecov (0.
|
14
|
+
rbs (1.3.3)
|
15
|
+
simplecov (0.21.2)
|
16
16
|
docile (~> 1.1)
|
17
17
|
simplecov-html (~> 0.11)
|
18
18
|
simplecov_json_formatter (~> 0.1)
|
19
19
|
simplecov-html (0.12.3)
|
20
|
-
simplecov_json_formatter (0.1.
|
21
|
-
stackprof (0.2.
|
22
|
-
test-unit (3.
|
20
|
+
simplecov_json_formatter (0.1.3)
|
21
|
+
stackprof (0.2.17)
|
22
|
+
test-unit (3.4.2)
|
23
23
|
power_assert
|
24
24
|
|
25
25
|
PLATFORMS
|
@@ -36,4 +36,4 @@ DEPENDENCIES
|
|
36
36
|
typeprof!
|
37
37
|
|
38
38
|
BUNDLED WITH
|
39
|
-
2.2.
|
39
|
+
2.2.15
|
data/lib/typeprof/analyzer.rb
CHANGED
@@ -277,20 +277,23 @@ module TypeProf
|
|
277
277
|
@pending_execution = {}
|
278
278
|
@executed_iseqs = Utils::MutableSet.new
|
279
279
|
|
280
|
-
@
|
280
|
+
@loaded_files = {}
|
281
281
|
|
282
282
|
@rbs_reader = RBSReader.new
|
283
283
|
|
284
284
|
@terminated = false
|
285
285
|
|
286
286
|
@anonymous_struct_gen_id = 0
|
287
|
+
|
288
|
+
@types_being_shown = []
|
289
|
+
@namespace = nil
|
287
290
|
end
|
288
291
|
|
289
292
|
def add_entrypoint(iseq)
|
290
293
|
@entrypoints << iseq
|
291
294
|
end
|
292
295
|
|
293
|
-
attr_reader :return_envs, :
|
296
|
+
attr_reader :return_envs, :loaded_files, :rbs_reader
|
294
297
|
|
295
298
|
def get_env(ep)
|
296
299
|
@ep2env[ep]
|
@@ -329,9 +332,10 @@ module TypeProf
|
|
329
332
|
@cvars = VarTable.new
|
330
333
|
@absolute_path = absolute_path
|
331
334
|
@namespace = nil
|
335
|
+
@subclasses = []
|
332
336
|
end
|
333
337
|
|
334
|
-
attr_reader :kind, :modules, :consts, :methods, :ivars, :cvars, :absolute_path
|
338
|
+
attr_reader :kind, :modules, :consts, :methods, :ivars, :cvars, :absolute_path, :subclasses
|
335
339
|
attr_accessor :name, :klass_obj
|
336
340
|
|
337
341
|
def mix_module(kind, mod, type_args, singleton, absolute_path)
|
@@ -445,6 +449,7 @@ module TypeProf
|
|
445
449
|
idx = @class_defs.size
|
446
450
|
if superclass
|
447
451
|
@class_defs[idx] = ClassDef.new(:class, show_name, absolute_path)
|
452
|
+
@class_defs[superclass.idx].subclasses << idx unless superclass == :__root__
|
448
453
|
klass = Type::Class.new(:class, idx, type_params, superclass, show_name)
|
449
454
|
@class_defs[idx].klass_obj = klass
|
450
455
|
cbase ||= klass # for bootstrap
|
@@ -471,6 +476,7 @@ module TypeProf
|
|
471
476
|
superclass = Type::Builtin[:struct]
|
472
477
|
name = "AnonymousStruct_generated_#{ @anonymous_struct_gen_id += 1 }"
|
473
478
|
@class_defs[idx] = ClassDef.new(:class, [name], ep.ctx.iseq.absolute_path)
|
479
|
+
#@class_defs[superclass.idx].subclasses << idx # needed?
|
474
480
|
klass = Type::Class.new(:class, idx, [], superclass, name)
|
475
481
|
add_superclass_type_args!(klass, [Type.any])
|
476
482
|
@class_defs[idx].klass_obj = klass
|
@@ -526,6 +532,13 @@ module TypeProf
|
|
526
532
|
end
|
527
533
|
end
|
528
534
|
|
535
|
+
def traverse_subclasses(klass, &blk)
|
536
|
+
@class_defs[klass.idx].subclasses.each do |subclass|
|
537
|
+
yield @class_defs[subclass]
|
538
|
+
traverse_subclasses(@class_defs[subclass].klass_obj, &blk)
|
539
|
+
end
|
540
|
+
end
|
541
|
+
|
529
542
|
def search_method(klass, singleton, mid, &blk)
|
530
543
|
# XXX: support method alias correctly
|
531
544
|
klass_orig = klass
|
@@ -545,7 +558,18 @@ module TypeProf
|
|
545
558
|
end
|
546
559
|
end
|
547
560
|
|
548
|
-
def get_method(klass, singleton, mid)
|
561
|
+
def get_method(klass, singleton, include_subclasses, mid)
|
562
|
+
if include_subclasses
|
563
|
+
subclasses_mthds = []
|
564
|
+
traverse_subclasses(klass) do |subclass|
|
565
|
+
subclass.search_method(singleton, mid, {}) do |mthds,|
|
566
|
+
subclasses_mthds.concat(mthds.to_a)
|
567
|
+
end
|
568
|
+
end
|
569
|
+
search_method(klass, singleton, mid) {|mthds,| return subclasses_mthds + mthds.to_a }
|
570
|
+
return subclasses_mthds
|
571
|
+
end
|
572
|
+
|
549
573
|
search_method(klass, singleton, mid) {|mthds,| return mthds }
|
550
574
|
end
|
551
575
|
|
@@ -646,9 +670,10 @@ module TypeProf
|
|
646
670
|
if klass == Type.any
|
647
671
|
self
|
648
672
|
else
|
649
|
-
mdefs = get_method(klass, singleton, orig_mid)
|
673
|
+
mdefs = get_method(klass, singleton, false, orig_mid) # XXX: include_subclass == false??
|
650
674
|
if mdefs
|
651
|
-
|
675
|
+
# dup is needed for `alias foo foo` (otherwise, "can't add a new key into hash during iteration" error occurs)
|
676
|
+
mdefs.dup.each do |mdef|
|
652
677
|
@class_defs[klass.idx].add_method(alias_mid, singleton, AliasMethodDef.new(orig_mid, mdef, ep))
|
653
678
|
end
|
654
679
|
end
|
@@ -755,24 +780,32 @@ module TypeProf
|
|
755
780
|
end
|
756
781
|
end
|
757
782
|
|
758
|
-
def
|
783
|
+
def identify_class_for_ivar(recv, var)
|
784
|
+
klass, singleton = recv.method_dispatch_info
|
785
|
+
return nil unless klass
|
786
|
+
search_method(klass, singleton, var) do |mthds, klass0, singleton0|
|
787
|
+
if mthds.any? {|mthd| mthd.is_a?(AttrMethodDef) }
|
788
|
+
return klass0, singleton
|
789
|
+
end
|
790
|
+
end
|
791
|
+
return klass, singleton
|
792
|
+
end
|
793
|
+
|
794
|
+
def get_ivar(recv, var)
|
759
795
|
recv = recv.base_type while recv.respond_to?(:base_type)
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
when Type::Any
|
766
|
-
return
|
796
|
+
|
797
|
+
klass, singleton = identify_class_for_ivar(recv, var.to_s[1..].to_sym) # search attr_reader
|
798
|
+
|
799
|
+
if klass
|
800
|
+
return @class_defs[klass.idx], singleton
|
767
801
|
else
|
768
|
-
|
769
|
-
return
|
802
|
+
return nil
|
770
803
|
end
|
771
804
|
end
|
772
805
|
|
773
806
|
def add_ivar_read!(recv, var, ep, &ctn)
|
774
807
|
recv.each_child do |recv|
|
775
|
-
class_def, singleton = get_ivar(recv)
|
808
|
+
class_def, singleton = get_ivar(recv, var)
|
776
809
|
next unless class_def
|
777
810
|
class_def.ivars.add_read!([singleton, var], ep, &ctn)
|
778
811
|
end
|
@@ -780,7 +813,7 @@ module TypeProf
|
|
780
813
|
|
781
814
|
def add_ivar_write!(recv, var, ty, ep)
|
782
815
|
recv.each_child do |recv|
|
783
|
-
class_def, singleton = get_ivar(recv)
|
816
|
+
class_def, singleton = get_ivar(recv, var)
|
784
817
|
next unless class_def
|
785
818
|
class_def.ivars.add_write!([singleton, var], ty, ep, self)
|
786
819
|
end
|
@@ -901,7 +934,16 @@ module TypeProf
|
|
901
934
|
prologue_env = Env.new(StaticEnv.new(Type.bot, Type.nil, false, true), [], [], Utils::HashWrapper.new({}))
|
902
935
|
|
903
936
|
until @entrypoints.empty?
|
904
|
-
|
937
|
+
entrypoint = @entrypoints.shift
|
938
|
+
if entrypoint.is_a?(String)
|
939
|
+
file = entrypoint
|
940
|
+
next if @loaded_files[File.expand_path(file)]
|
941
|
+
iseq = ISeq.compile(file)
|
942
|
+
else
|
943
|
+
iseq = entrypoint
|
944
|
+
end
|
945
|
+
|
946
|
+
@loaded_files[iseq.absolute_path] = true
|
905
947
|
ep, env = TypeProf.starting_state(iseq)
|
906
948
|
merge_env(ep, env)
|
907
949
|
add_callsite!(ep.ctx, prologue_ep, prologue_env) {|ty, ep| }
|
@@ -1077,15 +1119,16 @@ module TypeProf
|
|
1077
1119
|
env = @ep2env[ep]
|
1078
1120
|
raise "nil env" unless env
|
1079
1121
|
|
1080
|
-
insn
|
1122
|
+
insn = ep.ctx.iseq.insns[ep.pc]
|
1123
|
+
operands = insn.operands
|
1081
1124
|
|
1082
1125
|
if Config.verbose >= 2
|
1083
1126
|
# XXX: more dedicated output
|
1084
1127
|
puts "DEBUG: stack=%p" % [env.stack]
|
1085
|
-
puts "DEBUG: %s (%s) PC=%d insn=%s sp=%d" % [ep.source_location, ep.ctx.iseq.name, ep.pc, insn, env.stack.size]
|
1128
|
+
puts "DEBUG: %s (%s) PC=%d insn=%s sp=%d" % [ep.source_location, ep.ctx.iseq.name, ep.pc, insn.insn, env.stack.size]
|
1086
1129
|
end
|
1087
1130
|
|
1088
|
-
case insn
|
1131
|
+
case insn.insn
|
1089
1132
|
when :_iseq_body_start
|
1090
1133
|
# XXX: reconstruct and record the method signature
|
1091
1134
|
iseq = ep.ctx.iseq
|
@@ -1316,12 +1359,10 @@ module TypeProf
|
|
1316
1359
|
when :send
|
1317
1360
|
env, recvs, mid, aargs = setup_actual_arguments(:method, operands, ep, env)
|
1318
1361
|
recvs = Type.any if recvs == Type.bot
|
1319
|
-
recvs
|
1320
|
-
|
1321
|
-
|
1322
|
-
|
1323
|
-
merge_env(ep.next, nenv)
|
1324
|
-
end
|
1362
|
+
do_send(recvs, mid, aargs, ep, env) do |ret_ty, ep, env|
|
1363
|
+
nenv, ret_ty, = localize_type(ret_ty, env, ep)
|
1364
|
+
nenv = nenv.push(ret_ty)
|
1365
|
+
merge_env(ep.next, nenv)
|
1325
1366
|
end
|
1326
1367
|
return
|
1327
1368
|
when :recv_getlocal_send_branch
|
@@ -1389,24 +1430,22 @@ module TypeProf
|
|
1389
1430
|
send_operands, branch_operands = operands
|
1390
1431
|
env, recvs, mid, aargs = setup_actual_arguments(:method, send_operands, ep, env)
|
1391
1432
|
recvs = Type.any if recvs == Type.bot
|
1392
|
-
recvs
|
1393
|
-
|
1394
|
-
env, ret_ty, = localize_type(ret_ty, env, ep)
|
1433
|
+
do_send(recvs, mid, aargs, ep, env) do |ret_ty, ep, env|
|
1434
|
+
env, ret_ty, = localize_type(ret_ty, env, ep)
|
1395
1435
|
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1436
|
+
branchtype, target, = branch_operands
|
1437
|
+
# branchtype: :if or :unless or :nil
|
1438
|
+
ep_then = ep.next
|
1439
|
+
ep_else = ep.jump(target)
|
1400
1440
|
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
end
|
1441
|
+
case ret_ty
|
1442
|
+
when Type::Instance.new(Type::Builtin[:true])
|
1443
|
+
merge_env(branchtype == :if ? ep_else : ep_then, env)
|
1444
|
+
when Type::Instance.new(Type::Builtin[:false])
|
1445
|
+
merge_env(branchtype == :if ? ep_then : ep_else, env)
|
1446
|
+
else
|
1447
|
+
merge_env(ep_then, env)
|
1448
|
+
merge_env(ep_else, env)
|
1410
1449
|
end
|
1411
1450
|
end
|
1412
1451
|
return
|
@@ -1440,12 +1479,10 @@ module TypeProf
|
|
1440
1479
|
# XXX: this decomposition is really needed??
|
1441
1480
|
# It calls `Object.new` with union receiver which causes an error, but
|
1442
1481
|
# it may be a fault of builtin Object.new implementation.
|
1443
|
-
recv
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
merge_env(ep.next, nenv)
|
1448
|
-
end
|
1482
|
+
meth.do_send(recv, mid, aargs, ep, env, self) do |ret_ty, ep, env|
|
1483
|
+
nenv, ret_ty, = localize_type(ret_ty, env, ep)
|
1484
|
+
nenv = nenv.push(ret_ty)
|
1485
|
+
merge_env(ep.next, nenv)
|
1449
1486
|
end
|
1450
1487
|
end
|
1451
1488
|
end
|
@@ -1606,7 +1643,7 @@ module TypeProf
|
|
1606
1643
|
return
|
1607
1644
|
end
|
1608
1645
|
|
1609
|
-
when :getlocal
|
1646
|
+
when :getlocal
|
1610
1647
|
var_idx, scope_idx, _escaped = operands
|
1611
1648
|
if scope_idx == 0
|
1612
1649
|
ty = env.get_local(-var_idx+2)
|
@@ -1647,18 +1684,12 @@ module TypeProf
|
|
1647
1684
|
getlocal_operands, _dup_operands, branch_operands = operands
|
1648
1685
|
var_idx, _scope_idx, _escaped = getlocal_operands
|
1649
1686
|
ret_ty = env.get_local(-var_idx+2)
|
1650
|
-
unless ret_ty
|
1651
|
-
p env.locals
|
1652
|
-
raise
|
1653
|
-
end
|
1654
1687
|
|
1655
1688
|
branchtype, target, = branch_operands
|
1656
1689
|
# branchtype: :if or :unless or :nil
|
1657
1690
|
ep_then = ep.next
|
1658
1691
|
ep_else = ep.jump(target)
|
1659
1692
|
|
1660
|
-
var_idx, _scope_idx, _escaped = getlocal_operands
|
1661
|
-
|
1662
1693
|
ret_ty.each_child do |ret_ty|
|
1663
1694
|
flow_env = env.local_update(-var_idx+2, ret_ty).push(ret_ty)
|
1664
1695
|
case ret_ty
|
@@ -1672,6 +1703,31 @@ module TypeProf
|
|
1672
1703
|
end
|
1673
1704
|
end
|
1674
1705
|
return
|
1706
|
+
when :dup_setlocal_branch
|
1707
|
+
_dup_operands, setlocal_operands, branch_operands = operands
|
1708
|
+
|
1709
|
+
env, (ret_ty,) = env.pop(1)
|
1710
|
+
|
1711
|
+
var_idx, _scope_idx, _escaped = setlocal_operands
|
1712
|
+
|
1713
|
+
branchtype, target, = branch_operands
|
1714
|
+
# branchtype: :if or :unless or :nil
|
1715
|
+
ep_then = ep.next
|
1716
|
+
ep_else = ep.jump(target)
|
1717
|
+
|
1718
|
+
ret_ty.each_child do |ret_ty|
|
1719
|
+
flow_env = env.local_update(-var_idx+2, ret_ty)
|
1720
|
+
case ret_ty
|
1721
|
+
when Type.any
|
1722
|
+
merge_env(ep_then, flow_env)
|
1723
|
+
merge_env(ep_else, flow_env)
|
1724
|
+
when Type::Instance.new(Type::Builtin[:false]), Type.nil
|
1725
|
+
merge_env(branchtype == :if ? ep_then : ep_else, flow_env)
|
1726
|
+
else
|
1727
|
+
merge_env(branchtype == :if ? ep_else : ep_then, flow_env)
|
1728
|
+
end
|
1729
|
+
end
|
1730
|
+
return
|
1675
1731
|
when :getlocal_checkmatch_branch
|
1676
1732
|
getlocal_operands, branch_operands = operands
|
1677
1733
|
var_idx, _scope_idx, _escaped = getlocal_operands
|
@@ -1935,7 +1991,7 @@ module TypeProf
|
|
1935
1991
|
end
|
1936
1992
|
env = env.push(ty)
|
1937
1993
|
else
|
1938
|
-
raise "Unknown insn: #{ insn }"
|
1994
|
+
raise "Unknown insn: #{ insn.insn }"
|
1939
1995
|
end
|
1940
1996
|
|
1941
1997
|
add_edge(ep, ep)
|
@@ -2133,30 +2189,32 @@ module TypeProf
|
|
2133
2189
|
return env, recv, mid, aargs
|
2134
2190
|
end
|
2135
2191
|
|
2136
|
-
def do_send(
|
2137
|
-
|
2138
|
-
|
2139
|
-
|
2140
|
-
|
2141
|
-
|
2142
|
-
|
2143
|
-
|
2144
|
-
klass, singleton = recv.method_dispatch_info
|
2145
|
-
meths = get_method(klass, singleton, mid) if klass
|
2146
|
-
if meths
|
2147
|
-
meths.each do |meth|
|
2148
|
-
meth.do_send(recv, mid, aargs, ep, env, self, &ctn)
|
2149
|
-
end
|
2192
|
+
def do_send(recvs, mid, aargs, ep, env, &ctn)
|
2193
|
+
recvs.each_child do |recv|
|
2194
|
+
case recv
|
2195
|
+
when Type::Void
|
2196
|
+
error(ep, "void's method is called: #{ globalize_type(recv, env, ep).screen_name(self) }##{ mid }")
|
2197
|
+
ctn[Type.any, ep, env]
|
2198
|
+
when Type::Any
|
2199
|
+
ctn[Type.any, ep, env]
|
2150
2200
|
else
|
2151
|
-
|
2201
|
+
klass, singleton, include_subclasses = recv.method_dispatch_info
|
2202
|
+
meths = get_method(klass, singleton, include_subclasses, mid) if klass
|
2152
2203
|
if meths
|
2153
|
-
aargs = aargs.for_method_missing(Type::Symbol.new(mid, Type::Instance.new(Type::Builtin[:sym])))
|
2154
2204
|
meths.each do |meth|
|
2155
|
-
meth.do_send(recv,
|
2205
|
+
meth.do_send(recv, mid, aargs, ep, env, self, &ctn)
|
2156
2206
|
end
|
2157
2207
|
else
|
2158
|
-
|
2159
|
-
|
2208
|
+
meths = get_method(klass, singleton, include_subclasses, :method_missing) if klass
|
2209
|
+
if meths
|
2210
|
+
aargs = aargs.for_method_missing(Type::Symbol.new(mid, Type::Instance.new(Type::Builtin[:sym])))
|
2211
|
+
meths.each do |meth|
|
2212
|
+
meth.do_send(recv, :method_missing, aargs, ep, env, self, &ctn)
|
2213
|
+
end
|
2214
|
+
else
|
2215
|
+
error(ep, "undefined method: #{ globalize_type(recv, env, ep).screen_name(self) }##{ mid }")
|
2216
|
+
ctn[Type.any, ep, env]
|
2217
|
+
end
|
2160
2218
|
end
|
2161
2219
|
end
|
2162
2220
|
end
|
@@ -2167,7 +2225,7 @@ module TypeProf
|
|
2167
2225
|
if blk.is_a?(Type::Proc)
|
2168
2226
|
blk.block_body.do_call(aargs, ep, env, self, replace_recv_ty: replace_recv_ty, replace_cref: replace_cref, &ctn)
|
2169
2227
|
else
|
2170
|
-
warn(ep, "non-proc is passed as a block")
|
2228
|
+
warn(ep, "non-proc is passed as a block") if blk != Type.any
|
2171
2229
|
ctn[Type.any, ep, env]
|
2172
2230
|
end
|
2173
2231
|
end
|
@@ -2241,7 +2299,11 @@ module TypeProf
|
|
2241
2299
|
next unless @block_to_ctx[blk.block_body] # this occurs when screen_name is called before type-profiling finished (e.g., error message)
|
2242
2300
|
@block_to_ctx[blk.block_body].each do |blk_ctx|
|
2243
2301
|
if farg_tys
|
2244
|
-
|
2302
|
+
if @method_signatures[blk_ctx]
|
2303
|
+
farg_tys = farg_tys.merge_as_block_arguments(@method_signatures[blk_ctx])
|
2304
|
+
else
|
2305
|
+
# this occurs when screen_name is called before type-profiling finished (e.g., error message)
|
2306
|
+
end
|
2245
2307
|
else
|
2246
2308
|
farg_tys = @method_signatures[blk_ctx]
|
2247
2309
|
end
|
@@ -2251,17 +2313,24 @@ module TypeProf
|
|
2251
2313
|
end
|
2252
2314
|
end
|
2253
2315
|
|
2254
|
-
|
2255
|
-
ret_ty = ret_ty.screen_name(self)
|
2256
|
-
ret_ty = (ret_ty.include?("|") ? "(#{ ret_ty })" : ret_ty) # XXX?
|
2316
|
+
return Type.any.screen_name(self) if @types_being_shown.include?(farg_tys) || @types_being_shown.include?(ret_ty)
|
2257
2317
|
|
2258
|
-
|
2259
|
-
|
2318
|
+
begin
|
2319
|
+
@types_being_shown << farg_tys << ret_ty
|
2320
|
+
farg_tys = farg_tys ? farg_tys.screen_name(nil, self) : "(unknown)"
|
2321
|
+
ret_ty = ret_ty.screen_name(self)
|
2322
|
+
ret_ty = (ret_ty.include?("|") ? "(#{ ret_ty })" : ret_ty) # XXX?
|
2323
|
+
|
2324
|
+
farg_tys = farg_tys + " " if farg_tys != ""
|
2325
|
+
"^#{ farg_tys }-> #{ ret_ty }"
|
2326
|
+
ensure
|
2327
|
+
@types_being_shown.pop(2)
|
2328
|
+
end
|
2260
2329
|
end
|
2261
2330
|
|
2262
2331
|
def show_method_signature(ctx)
|
2263
2332
|
farg_tys = @method_signatures[ctx]
|
2264
|
-
ret_ty = @return_values[ctx] || Type.bot
|
2333
|
+
ret_ty = ctx.mid == :initialize ? Type::Void.new : @return_values[ctx] || Type.bot
|
2265
2334
|
|
2266
2335
|
untyped = farg_tys.include_untyped?(self) || ret_ty.include_untyped?(self)
|
2267
2336
|
|