typeprof 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|