typeprof 0.1.4 → 0.2.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 +2 -2
- data/README.md +1 -1
- data/doc/doc.ja.md +5 -0
- data/doc/doc.md +9 -5
- data/lib/typeprof/analyzer.rb +97 -69
- data/lib/typeprof/builtin.rb +96 -92
- data/lib/typeprof/cli.rb +42 -4
- data/lib/typeprof/export.rb +36 -20
- data/lib/typeprof/import.rb +406 -365
- data/lib/typeprof/iseq.rb +1 -1
- data/lib/typeprof/method.rb +34 -33
- data/lib/typeprof/type.rb +1 -4
- data/run.sh +1 -1
- data/smoke/block13.rb +9 -0
- data/smoke/block13.rbs +3 -0
- data/smoke/class.rb +2 -0
- data/smoke/constant1.rb +3 -0
- data/smoke/demo5.rb +3 -0
- data/smoke/gvar.rb +1 -1
- data/smoke/gvar2.rb +17 -0
- data/smoke/gvar2.rbs +1 -0
- data/smoke/inheritance2.rb +6 -0
- data/smoke/ivar3.rb +16 -0
- data/smoke/ivar3.rbs +3 -0
- data/smoke/manual-rbs2.rb +1 -1
- data/smoke/manual-rbs3.rb +12 -0
- data/smoke/manual-rbs3.rbs +3 -0
- data/smoke/module4.rb +3 -0
- data/smoke/multiple-superclass.rb +8 -0
- data/smoke/rbs-alias.rb +9 -0
- data/smoke/rbs-alias.rbs +4 -0
- data/smoke/rbs-attr.rb +26 -0
- data/smoke/rbs-attr.rbs +5 -0
- data/smoke/rbs-vars.rb +39 -0
- data/smoke/rbs-vars.rbs +7 -0
- data/smoke/struct.rb +3 -0
- data/smoke/super1.rb +18 -0
- data/smoke/union-recv.rb +6 -0
- data/tools/setup-insns-def.rb +1 -1
- data/tools/stackprof-wrapper.rb +1 -1
- data/typeprof.gemspec +10 -4
- metadata +26 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6c01f41e130c6e3bbc112520904ed710a75dea1b167ea112e96a321cd1bceadf
|
4
|
+
data.tar.gz: 1b61e75c07cc8d24570bd998ea852f850b22264aaa1eed1bda425efe11660fba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ba66753bc6fe6b21939449ede398ee31c27aa06893884a3e93baebcf60439c9552fa0b1da1b8fd6158f83ef012966f275c83055ba94d2974c10f694e031c40ab
|
7
|
+
data.tar.gz: 6f6d9e688c024eefead28c9fe847686d172919a0c3ae0f5f6441bcb79d947710265e77dc52e4c5d44be699d7ea6bcd978943d0a898621956e6991a19c3874ac0
|
data/Gemfile.lock
CHANGED
@@ -16,7 +16,7 @@ GIT
|
|
16
16
|
PATH
|
17
17
|
remote: .
|
18
18
|
specs:
|
19
|
-
typeprof (0.1.
|
19
|
+
typeprof (0.1.4)
|
20
20
|
rbs (>= 0.12.0)
|
21
21
|
|
22
22
|
GEM
|
@@ -26,7 +26,7 @@ GEM
|
|
26
26
|
docile (1.3.2)
|
27
27
|
power_assert (1.2.0)
|
28
28
|
rake (13.0.1)
|
29
|
-
rbs (0.
|
29
|
+
rbs (0.14.0)
|
30
30
|
stackprof (0.2.15)
|
31
31
|
test-unit (3.3.6)
|
32
32
|
power_assert
|
data/README.md
CHANGED
data/doc/doc.ja.md
CHANGED
@@ -25,6 +25,11 @@ $ typeprof sig/app.rbs app.rb -o sig/app.gen.rbs
|
|
25
25
|
* `-o OUTFILE`: 標準出力ではなく、指定ファイル名に出力する
|
26
26
|
* `-q`: 解析の進捗を表示しない
|
27
27
|
* `-v`: 解析の詳細ログを表示する(現状ではデバッグ用出力に近い)
|
28
|
+
* `-I DIR`: `require`のファイル探索ディレクトリを追加する
|
29
|
+
* `-r GEMNAME`: `GEMNAME`に対応するRBSをロードする
|
30
|
+
* `--exclude-dir DIR`: `DIR`以下のファイルの解析結果を出力から省略する。後に指定されているほうが優先される(`--include-dir foo --exclude-dir foo/bar`の場合う、foo/bar/baz.rbの結果は出力されず、foo/baz.rbの結果は出力される)。
|
31
|
+
* `--include-dir DIR`: `DIR`以下のファイルの解析結果を出力に含める。後に指定されているほうが優先される(`--exclude-dir foo --include-dir foo/bar`の場合、
|
32
|
+
foo/bar/baz.rbの結果は出力されるが、foo/baz.rbの結果は出力されない)。
|
28
33
|
* `-fshow-errors`: 実行中に見つけたバグの可能性を出力します(多くの場合、大量のfalse positiveが出ます)。
|
29
34
|
* `-fpedantic-output`: デフォルトでは`A | untyped`と推定されたところを単に`A`と出力しますが、より生の出力、つまり`A | untyped`と出力します。
|
30
35
|
* `-fshow-container-raw-elements`: (後で書く)
|
data/doc/doc.md
CHANGED
@@ -25,6 +25,10 @@ Here is a list of currently avaiable options:
|
|
25
25
|
* `-o OUTFILE`: Write the analyze result to OUTFILE instead of standard output
|
26
26
|
* `-q`: Hide the progress indicator
|
27
27
|
* `-v`: Show the analysis log (Currently, the log is just for debugging and may become very huge)
|
28
|
+
* `-I DIR`: Add `DIR` to the file search path of `require`
|
29
|
+
* `-r GEMNAME`: Load the RBS files of `GEMNAME`
|
30
|
+
* `--exclude-dir DIR`: Omit the result of files that are placed under the directory `DIR`. If there are some directory specifications, the latter one is stronger. (Assuming that `--include-dir foo --exclude-dir foo/bar` is specified, the analysis result of foo/bar/baz.rb is omitted, but foo/baz.rb is shown.)
|
31
|
+
* `--include-dir DIR`: Show the result of files that are placed under the directory `DIR`. If there are some directory specifications, the latter one is stronger. (Assuming that `--exclude-dir foo --include-dir foo/bar` is specified, the analysis result of foo/bar/baz.rb is shown, but foo/baz.rb is omitted.)
|
28
32
|
* `-fshow-errors`: Prints out possible bugs found during execution (often a lot of false positives).
|
29
33
|
* `-fpedantic-output`: When TypeProf inferred a type `A | untyped`, it simply outputs `A` by default. But this option forces it to output `A | untyped`.
|
30
34
|
* `-fshow-container-raw-elements`: (undocumented yet)
|
@@ -50,7 +54,7 @@ p foo(42) #=> String
|
|
50
54
|
The analysis results of TypeProf are as follows.
|
51
55
|
|
52
56
|
```
|
53
|
-
$ ruby exe/
|
57
|
+
$ ruby exe/typeprof test.rb
|
54
58
|
# Revealed types
|
55
59
|
# test.rb:2 #=> Integer
|
56
60
|
# test.rb:6 #=> String
|
@@ -84,7 +88,7 @@ p Foo.new.a #=> Integer | String
|
|
84
88
|
```
|
85
89
|
|
86
90
|
```
|
87
|
-
$ ruby exe/
|
91
|
+
$ ruby exe/typeprof test.rb
|
88
92
|
# Revealed types
|
89
93
|
# test.rb:11 #=> Integer | String
|
90
94
|
|
@@ -299,7 +303,7 @@ class Object
|
|
299
303
|
def foo: (Integer) -> Integer | (String) -> String
|
300
304
|
end
|
301
305
|
```
|
302
|
-
|
306
|
+
|
303
307
|
```
|
304
308
|
# test.rb
|
305
309
|
def foo(n)
|
@@ -386,9 +390,9 @@ You can update the types; this allows the following code to initialize the array
|
|
386
390
|
```
|
387
391
|
def foo
|
388
392
|
a = []
|
389
|
-
|
393
|
+
|
390
394
|
100.times {|n| a << n.to_s}
|
391
|
-
|
395
|
+
|
392
396
|
a
|
393
397
|
end
|
394
398
|
|
data/lib/typeprof/analyzer.rb
CHANGED
@@ -235,8 +235,6 @@ module TypeProf
|
|
235
235
|
@block_to_ctx = {}
|
236
236
|
@gvar_table = VarTable.new
|
237
237
|
|
238
|
-
@include_relations = {}
|
239
|
-
|
240
238
|
@errors = []
|
241
239
|
@reveal_types = {}
|
242
240
|
@backward_edges = {}
|
@@ -274,32 +272,37 @@ module TypeProf
|
|
274
272
|
attr_reader :class_defs
|
275
273
|
|
276
274
|
class ClassDef # or ModuleDef
|
277
|
-
def initialize(kind, name, superclass)
|
275
|
+
def initialize(kind, name, superclass, absolute_path)
|
278
276
|
@kind = kind
|
279
277
|
@superclass = superclass
|
280
|
-
@modules = { true =>
|
278
|
+
@modules = { true => {}, false => {} }
|
281
279
|
@name = name
|
282
280
|
@consts = {}
|
283
281
|
@methods = {}
|
284
282
|
@ivars = VarTable.new
|
285
283
|
@cvars = VarTable.new
|
284
|
+
@absolute_path = absolute_path
|
286
285
|
end
|
287
286
|
|
288
|
-
attr_reader :kind, :modules, :methods, :superclass, :ivars, :cvars
|
287
|
+
attr_reader :kind, :modules, :methods, :superclass, :ivars, :cvars, :absolute_path
|
289
288
|
attr_accessor :name, :klass_obj
|
290
289
|
|
291
|
-
def include_module(mod,
|
290
|
+
def include_module(mod, absolute_path)
|
292
291
|
# XXX: need to check if mod is already included by the ancestors?
|
293
|
-
|
294
|
-
|
292
|
+
absolute_paths = @modules[false][mod]
|
293
|
+
unless absolute_paths
|
294
|
+
@modules[false][mod] = absolute_paths = Utils::MutableSet.new
|
295
295
|
end
|
296
|
+
absolute_paths << absolute_path
|
296
297
|
end
|
297
298
|
|
298
|
-
def extend_module(mod,
|
299
|
+
def extend_module(mod, absolute_path)
|
299
300
|
# XXX: need to check if mod is already included by the ancestors?
|
300
|
-
|
301
|
-
|
301
|
+
absolute_paths = @modules[true][mod]
|
302
|
+
unless absolute_paths
|
303
|
+
@modules[true][mod] = absolute_paths = Utils::MutableSet.new
|
302
304
|
end
|
305
|
+
absolute_paths << absolute_path
|
303
306
|
end
|
304
307
|
|
305
308
|
def get_constant(name)
|
@@ -315,7 +318,7 @@ module TypeProf
|
|
315
318
|
|
316
319
|
def get_method(mid, singleton)
|
317
320
|
@methods[[singleton, mid]] || begin
|
318
|
-
@modules[singleton].
|
321
|
+
@modules[singleton].each_key do |mod|
|
319
322
|
meth = mod.get_method(mid, false)
|
320
323
|
return meth if meth
|
321
324
|
end
|
@@ -336,22 +339,22 @@ module TypeProf
|
|
336
339
|
@methods[[singleton, mid]] << mdef
|
337
340
|
# Need to restart...?
|
338
341
|
end
|
342
|
+
|
343
|
+
def set_method(mid, singleton, mdef)
|
344
|
+
@methods[[singleton, mid]] = Utils::MutableSet.new
|
345
|
+
@methods[[singleton, mid]] << mdef
|
346
|
+
end
|
339
347
|
end
|
340
348
|
|
341
|
-
def include_module(including_mod, included_mod,
|
349
|
+
def include_module(including_mod, included_mod, absolute_path)
|
342
350
|
return if included_mod == Type.any
|
343
351
|
|
344
|
-
if visible
|
345
|
-
@include_relations[including_mod] ||= Utils::MutableSet.new
|
346
|
-
@include_relations[including_mod] << included_mod
|
347
|
-
end
|
348
|
-
|
349
352
|
including_mod = @class_defs[including_mod.idx]
|
350
353
|
included_mod.each_child do |included_mod|
|
351
354
|
if included_mod.is_a?(Type::Class)
|
352
355
|
included_mod = @class_defs[included_mod.idx]
|
353
356
|
if included_mod && included_mod.kind == :module
|
354
|
-
including_mod.include_module(included_mod,
|
357
|
+
including_mod.include_module(included_mod, absolute_path)
|
355
358
|
else
|
356
359
|
warn "including something that is not a module"
|
357
360
|
end
|
@@ -359,13 +362,13 @@ module TypeProf
|
|
359
362
|
end
|
360
363
|
end
|
361
364
|
|
362
|
-
def extend_module(extending_mod, extended_mod,
|
365
|
+
def extend_module(extending_mod, extended_mod, absolute_path)
|
363
366
|
extending_mod = @class_defs[extending_mod.idx]
|
364
367
|
extended_mod.each_child do |extended_mod|
|
365
368
|
if extended_mod.is_a?(Type::Class)
|
366
369
|
extended_mod = @class_defs[extended_mod.idx]
|
367
370
|
if extended_mod && extended_mod.kind == :module
|
368
|
-
extending_mod.extend_module(extended_mod,
|
371
|
+
extending_mod.extend_module(extended_mod, absolute_path)
|
369
372
|
else
|
370
373
|
warn "extending something that is not a module"
|
371
374
|
end
|
@@ -373,8 +376,8 @@ module TypeProf
|
|
373
376
|
end
|
374
377
|
end
|
375
378
|
|
376
|
-
def new_class(cbase, name, type_params, superclass)
|
377
|
-
if cbase && cbase.idx !=
|
379
|
+
def new_class(cbase, name, type_params, superclass, absolute_path)
|
380
|
+
if cbase && cbase.idx != 1
|
378
381
|
show_name = "#{ @class_defs[cbase.idx].name }::#{ name }"
|
379
382
|
else
|
380
383
|
show_name = name.to_s
|
@@ -386,7 +389,7 @@ module TypeProf
|
|
386
389
|
else
|
387
390
|
superclass_idx = superclass.idx
|
388
391
|
end
|
389
|
-
@class_defs[idx] = ClassDef.new(:class, show_name, superclass_idx)
|
392
|
+
@class_defs[idx] = ClassDef.new(:class, show_name, superclass_idx, absolute_path)
|
390
393
|
klass = Type::Class.new(:class, idx, type_params, superclass, show_name)
|
391
394
|
@class_defs[idx].klass_obj = klass
|
392
395
|
cbase ||= klass # for bootstrap
|
@@ -394,7 +397,7 @@ module TypeProf
|
|
394
397
|
return klass
|
395
398
|
else
|
396
399
|
# module
|
397
|
-
@class_defs[idx] = ClassDef.new(:module, show_name, nil)
|
400
|
+
@class_defs[idx] = ClassDef.new(:module, show_name, nil, absolute_path)
|
398
401
|
mod = Type::Class.new(:module, idx, type_params, nil, show_name)
|
399
402
|
@class_defs[idx].klass_obj = mod
|
400
403
|
add_constant(cbase, name, mod)
|
@@ -407,7 +410,7 @@ module TypeProf
|
|
407
410
|
|
408
411
|
idx = @class_defs.size
|
409
412
|
superclass = Type::Builtin[:struct]
|
410
|
-
@class_defs[idx] = ClassDef.new(:class, "(Struct)", superclass.idx)
|
413
|
+
@class_defs[idx] = ClassDef.new(:class, "(Struct)", superclass.idx, ep.ctx.iseq.absolute_path)
|
411
414
|
klass = Type::Class.new(:class, idx, [], superclass, "(Struct)")
|
412
415
|
@class_defs[idx].klass_obj = klass
|
413
416
|
|
@@ -487,12 +490,17 @@ module TypeProf
|
|
487
490
|
mdef
|
488
491
|
end
|
489
492
|
|
490
|
-
def
|
493
|
+
def set_method(klass, mid, singleton, mdef)
|
494
|
+
@class_defs[klass.idx].set_method(mid, singleton, mdef)
|
495
|
+
mdef
|
496
|
+
end
|
497
|
+
|
498
|
+
def add_attr_method(klass, absolute_path, mid, ivar, kind)
|
491
499
|
if kind == :reader || kind == :accessor
|
492
|
-
add_method(klass, mid, false, AttrMethodDef.new(ivar, :reader))
|
500
|
+
add_method(klass, mid, false, AttrMethodDef.new(ivar, :reader, absolute_path))
|
493
501
|
end
|
494
502
|
if kind == :writer || kind == :accessor
|
495
|
-
add_method(klass, :"#{ mid }=", false, AttrMethodDef.new(ivar, :writer))
|
503
|
+
add_method(klass, :"#{ mid }=", false, AttrMethodDef.new(ivar, :writer, absolute_path))
|
496
504
|
end
|
497
505
|
end
|
498
506
|
|
@@ -512,12 +520,12 @@ module TypeProf
|
|
512
520
|
add_method(recv_ty.klass, mid, true, TypedMethodDef.new([[fargs, ret_ty]]))
|
513
521
|
end
|
514
522
|
|
515
|
-
def
|
516
|
-
|
523
|
+
def set_custom_method(klass, mid, impl)
|
524
|
+
set_method(klass, mid, false, CustomMethodDef.new(impl))
|
517
525
|
end
|
518
526
|
|
519
|
-
def
|
520
|
-
|
527
|
+
def set_singleton_custom_method(klass, mid, impl)
|
528
|
+
set_method(klass, mid, true, CustomMethodDef.new(impl))
|
521
529
|
end
|
522
530
|
|
523
531
|
def alias_method(klass, singleton, new, old)
|
@@ -592,27 +600,39 @@ module TypeProf
|
|
592
600
|
end
|
593
601
|
|
594
602
|
class VarTable
|
603
|
+
Entry = Struct.new(:rbs_declared, :read_continuations, :type, :absolute_paths)
|
604
|
+
|
595
605
|
def initialize
|
596
|
-
@
|
606
|
+
@tbl = {}
|
597
607
|
end
|
598
608
|
|
599
|
-
attr_reader :write
|
600
|
-
|
601
609
|
def add_read!(site, ep, &ctn)
|
602
|
-
@
|
603
|
-
|
604
|
-
|
605
|
-
ctn[
|
610
|
+
entry = @tbl[site] ||= Entry.new(false, {}, Type.bot, Utils::MutableSet.new)
|
611
|
+
entry.read_continuations[ep] = ctn
|
612
|
+
entry.absolute_paths << ep.ctx.iseq.absolute_path
|
613
|
+
ctn[entry.type, ep]
|
606
614
|
end
|
607
615
|
|
608
|
-
def add_write!(site, ty,
|
609
|
-
@
|
610
|
-
|
611
|
-
|
612
|
-
|
616
|
+
def add_write!(site, ty, ep, scratch)
|
617
|
+
entry = @tbl[site] ||= Entry.new(!ep, {}, Type.bot, Utils::MutableSet.new)
|
618
|
+
if ep
|
619
|
+
if entry.rbs_declared
|
620
|
+
if !entry.type.consistent?(ty, {})
|
621
|
+
scratch.warn(ep, "inconsistent assignment to RBS-declared global variable")
|
622
|
+
return
|
623
|
+
end
|
624
|
+
end
|
625
|
+
entry.absolute_paths << ep.ctx.iseq.absolute_path
|
626
|
+
end
|
627
|
+
entry.type = entry.type.union(ty)
|
628
|
+
entry.read_continuations.each do |ep, ctn|
|
613
629
|
ctn[ty, ep]
|
614
630
|
end
|
615
631
|
end
|
632
|
+
|
633
|
+
def dump
|
634
|
+
@tbl
|
635
|
+
end
|
616
636
|
end
|
617
637
|
|
618
638
|
def get_ivar(recv)
|
@@ -637,11 +657,11 @@ module TypeProf
|
|
637
657
|
end
|
638
658
|
end
|
639
659
|
|
640
|
-
def add_ivar_write!(recv, var, ty,
|
660
|
+
def add_ivar_write!(recv, var, ty, ep)
|
641
661
|
recv.each_child do |recv|
|
642
662
|
class_def, singleton = get_ivar(recv)
|
643
663
|
next unless class_def
|
644
|
-
class_def.ivars.add_write!([singleton, var], ty,
|
664
|
+
class_def.ivars.add_write!([singleton, var], ty, ep, self)
|
645
665
|
end
|
646
666
|
end
|
647
667
|
|
@@ -653,11 +673,11 @@ module TypeProf
|
|
653
673
|
end
|
654
674
|
end
|
655
675
|
|
656
|
-
def add_cvar_write!(klass, var, ty,
|
676
|
+
def add_cvar_write!(klass, var, ty, ep)
|
657
677
|
klass.each_child do |klass|
|
658
678
|
class_def = @class_defs[klass.idx]
|
659
679
|
next unless class_def
|
660
|
-
class_def.cvars.add_write!(var, ty,
|
680
|
+
class_def.cvars.add_write!(var, ty, ep, self)
|
661
681
|
end
|
662
682
|
end
|
663
683
|
|
@@ -665,8 +685,8 @@ module TypeProf
|
|
665
685
|
@gvar_table.add_read!(var, ep, &ctn)
|
666
686
|
end
|
667
687
|
|
668
|
-
def add_gvar_write!(var, ty,
|
669
|
-
@gvar_table.add_write!(var, ty,
|
688
|
+
def add_gvar_write!(var, ty, ep)
|
689
|
+
@gvar_table.add_write!(var, ty, ep, self)
|
670
690
|
end
|
671
691
|
|
672
692
|
def error(ep, msg)
|
@@ -709,7 +729,7 @@ module TypeProf
|
|
709
729
|
gid = @alloc_site_to_global_id[id]
|
710
730
|
if gid
|
711
731
|
ty = globalize_type(elems.to_local_type(id), env, ep)
|
712
|
-
add_ivar_write!(*gid, ty)
|
732
|
+
add_ivar_write!(*gid, ty, ep)
|
713
733
|
end
|
714
734
|
menv
|
715
735
|
end
|
@@ -721,7 +741,7 @@ module TypeProf
|
|
721
741
|
gid = @alloc_site_to_global_id[id]
|
722
742
|
if gid
|
723
743
|
ty = globalize_type(elems.to_local_type(id), env, ep)
|
724
|
-
add_ivar_write!(*gid, ty)
|
744
|
+
add_ivar_write!(*gid, ty, ep)
|
725
745
|
end
|
726
746
|
env
|
727
747
|
end
|
@@ -749,18 +769,25 @@ module TypeProf
|
|
749
769
|
end
|
750
770
|
|
751
771
|
def type_profile
|
752
|
-
|
772
|
+
time = Time.now
|
773
|
+
step_counter = 0
|
753
774
|
stat_eps = Utils::MutableSet.new
|
754
775
|
while true
|
755
776
|
until @worklist.empty?
|
756
|
-
counter += 1
|
757
|
-
if counter % 1000 == 0 && Config.verbose >= 1
|
758
|
-
puts "iter %d, remain: %d" % [counter, @worklist.size]
|
759
|
-
#exit if counter == 20000
|
760
|
-
end
|
761
777
|
@ep = @worklist.deletemin
|
778
|
+
|
779
|
+
step_counter += 1
|
780
|
+
if Config.verbose >= 1
|
781
|
+
time2 = Time.now
|
782
|
+
if time2 - time >= 1
|
783
|
+
time = time2
|
784
|
+
$stderr << "\rType Profiling... (%d steps @ %s)\e[K" % [step_counter, @ep.source_location]
|
785
|
+
$stderr.flush
|
786
|
+
end
|
787
|
+
end
|
788
|
+
|
762
789
|
stat_eps << @ep
|
763
|
-
step(@ep)
|
790
|
+
step(@ep)
|
764
791
|
end
|
765
792
|
|
766
793
|
# XXX: it would be good to provide no-dummy-execution mode.
|
@@ -820,6 +847,7 @@ module TypeProf
|
|
820
847
|
end
|
821
848
|
end
|
822
849
|
end
|
850
|
+
$stderr.print "\r\e[K" if Config.verbose >= 1
|
823
851
|
|
824
852
|
stat_eps
|
825
853
|
end
|
@@ -829,7 +857,7 @@ module TypeProf
|
|
829
857
|
|
830
858
|
Reporters.show_reveal_types(self, @reveal_types, output)
|
831
859
|
|
832
|
-
Reporters.show_gvars(self, @gvar_table
|
860
|
+
Reporters.show_gvars(self, @gvar_table, output)
|
833
861
|
|
834
862
|
#RubySignatureExporter2.new(
|
835
863
|
# self, @include_relations, @ivar_table.write, @cvar_table.write, @class_defs
|
@@ -895,7 +923,7 @@ module TypeProf
|
|
895
923
|
|
896
924
|
def set_instance_variable(recv, var, ty, ep, env)
|
897
925
|
ty = globalize_type(ty, env, ep)
|
898
|
-
add_ivar_write!(recv, var, ty)
|
926
|
+
add_ivar_write!(recv, var, ty, ep)
|
899
927
|
end
|
900
928
|
|
901
929
|
def step(ep)
|
@@ -985,6 +1013,7 @@ module TypeProf
|
|
985
1013
|
recv = env.static_env.recv_ty
|
986
1014
|
if cref.klass.is_a?(Type::Class)
|
987
1015
|
typed_mdef = check_typed_method(cref.klass, mid, ep.ctx.cref.singleton)
|
1016
|
+
recv = Type::Instance.new(recv) if recv.is_a?(Type::Class)
|
988
1017
|
if typed_mdef
|
989
1018
|
mdef = ISeqMethodDef.new(iseq, cref)
|
990
1019
|
typed_mdef.each do |typed_mdef|
|
@@ -1000,7 +1029,6 @@ module TypeProf
|
|
1000
1029
|
end
|
1001
1030
|
end
|
1002
1031
|
|
1003
|
-
recv = Type::Instance.new(recv) if recv.is_a?(Type::Class)
|
1004
1032
|
pend_method_execution(iseq, meth, recv, mid, ep.ctx.cref)
|
1005
1033
|
end
|
1006
1034
|
else
|
@@ -1058,7 +1086,7 @@ module TypeProf
|
|
1058
1086
|
if cbase == Type.any
|
1059
1087
|
klass = Type.any
|
1060
1088
|
else
|
1061
|
-
klass = new_class(cbase, id, [], superclass)
|
1089
|
+
klass = new_class(cbase, id, [], superclass, ep.ctx.iseq.absolute_path)
|
1062
1090
|
end
|
1063
1091
|
end
|
1064
1092
|
end
|
@@ -1284,7 +1312,7 @@ module TypeProf
|
|
1284
1312
|
cbase = ep.ctx.cref.klass
|
1285
1313
|
ty = globalize_type(ty, env, ep)
|
1286
1314
|
# TODO: if superclass has the variable, it should be updated
|
1287
|
-
add_cvar_write!(cbase, var, ty)
|
1315
|
+
add_cvar_write!(cbase, var, ty, ep)
|
1288
1316
|
|
1289
1317
|
when :getclassvariable
|
1290
1318
|
var, = operands
|
@@ -1300,7 +1328,7 @@ module TypeProf
|
|
1300
1328
|
var, = operands
|
1301
1329
|
env, (ty,) = env.pop(1)
|
1302
1330
|
ty = globalize_type(ty, env, ep)
|
1303
|
-
add_gvar_write!(var, ty)
|
1331
|
+
add_gvar_write!(var, ty, ep)
|
1304
1332
|
|
1305
1333
|
when :getglobal
|
1306
1334
|
var, = operands
|
@@ -1311,7 +1339,6 @@ module TypeProf
|
|
1311
1339
|
env = env.push(ty)
|
1312
1340
|
else
|
1313
1341
|
add_gvar_read!(var, ep) do |ty, ep|
|
1314
|
-
ty = Type.nil if ty == Type.bot # HACK
|
1315
1342
|
nenv, ty = localize_type(ty, env, ep)
|
1316
1343
|
merge_env(ep.next, nenv.push(ty))
|
1317
1344
|
end
|
@@ -1754,7 +1781,7 @@ module TypeProf
|
|
1754
1781
|
meth.do_send(recv, mid, aargs, ep, env, self, &ctn)
|
1755
1782
|
end
|
1756
1783
|
else
|
1757
|
-
if recv != Type.any
|
1784
|
+
if recv != Type.any
|
1758
1785
|
error(ep, "undefined method: #{ globalize_type(recv, env, ep).screen_name(self) }##{ mid }")
|
1759
1786
|
end
|
1760
1787
|
ctn[Type.any, ep, env]
|
@@ -1773,6 +1800,7 @@ module TypeProf
|
|
1773
1800
|
blk_env = blk_env.replace_recv_ty(replace_recv_ty) if replace_recv_ty
|
1774
1801
|
arg_blk = aargs.blk_ty
|
1775
1802
|
aargs_ = aargs.lead_tys.map {|aarg| globalize_type(aarg, env, ep) }
|
1803
|
+
# XXX: aargs.opt_tys and aargs.kw_ty
|
1776
1804
|
argc = blk_iseq.fargs_format[:lead_num] || 0
|
1777
1805
|
# actual argc == 1, not array, formal argc == 1: yield 42 => do |x| : x=42
|
1778
1806
|
# actual argc == 1, array, formal argc == 1: yield [42,43,44] => do |x| : x=[42,43,44]
|
@@ -1823,7 +1851,7 @@ module TypeProf
|
|
1823
1851
|
locals = [Type.nil] * blk_iseq.locals.size
|
1824
1852
|
locals[blk_iseq.fargs_format[:block_start]] = arg_blk if blk_iseq.fargs_format[:block_start]
|
1825
1853
|
env_blk = blk_env.static_env.blk_ty
|
1826
|
-
nfargs = FormalArguments.new(aargs_, [], nil, [], nil, nil, env_blk)
|
1854
|
+
nfargs = FormalArguments.new(aargs_, [], nil, [], nil, nil, env_blk)
|
1827
1855
|
nctx = Context.new(blk_iseq, blk_ep.ctx.cref, nil)
|
1828
1856
|
nep = ExecutionPoint.new(nctx, 0, blk_ep)
|
1829
1857
|
nenv = Env.new(blk_env.static_env, locals, [], nil)
|