typeprof 0.1.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 +7 -0
- data/.github/workflows/main.yml +26 -0
- data/.gitignore +7 -0
- data/.gitmodules +6 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +41 -0
- data/README.md +53 -0
- data/Rakefile +10 -0
- data/doc/doc.ja.md +415 -0
- data/doc/doc.md +429 -0
- data/doc/ppl2019.pdf +0 -0
- data/exe/typeprof +5 -0
- data/lib/typeprof.rb +13 -0
- data/lib/typeprof/analyzer.rb +1911 -0
- data/lib/typeprof/builtin.rb +554 -0
- data/lib/typeprof/cli.rb +110 -0
- data/lib/typeprof/container-type.rb +626 -0
- data/lib/typeprof/export.rb +203 -0
- data/lib/typeprof/import.rb +546 -0
- data/lib/typeprof/insns-def.rb +61 -0
- data/lib/typeprof/iseq.rb +387 -0
- data/lib/typeprof/method.rb +267 -0
- data/lib/typeprof/type.rb +1092 -0
- data/lib/typeprof/utils.rb +209 -0
- data/run.sh +3 -0
- data/smoke/alias.rb +30 -0
- data/smoke/alias2.rb +19 -0
- data/smoke/any-cbase.rb +5 -0
- data/smoke/any1.rb +15 -0
- data/smoke/any2.rb +17 -0
- data/smoke/arguments.rb +16 -0
- data/smoke/array-each.rb +14 -0
- data/smoke/array-each2.rb +15 -0
- data/smoke/array-each3.rb +15 -0
- data/smoke/array-ltlt.rb +13 -0
- data/smoke/array-ltlt2.rb +16 -0
- data/smoke/array-map.rb +11 -0
- data/smoke/array-map2.rb +10 -0
- data/smoke/array-map3.rb +22 -0
- data/smoke/array-mul.rb +17 -0
- data/smoke/array-plus1.rb +10 -0
- data/smoke/array-plus2.rb +15 -0
- data/smoke/array-pop.rb +11 -0
- data/smoke/array-replace.rb +12 -0
- data/smoke/array-s-aref.rb +11 -0
- data/smoke/array1.rb +26 -0
- data/smoke/array10.rb +14 -0
- data/smoke/array11.rb +13 -0
- data/smoke/array12.rb +24 -0
- data/smoke/array13.rb +30 -0
- data/smoke/array14.rb +13 -0
- data/smoke/array2.rb +27 -0
- data/smoke/array3.rb +25 -0
- data/smoke/array4.rb +14 -0
- data/smoke/array5.rb +13 -0
- data/smoke/array6.rb +14 -0
- data/smoke/array7.rb +13 -0
- data/smoke/array8.rb +13 -0
- data/smoke/array9.rb +12 -0
- data/smoke/attr.rb +28 -0
- data/smoke/backtrace.rb +32 -0
- data/smoke/block1.rb +22 -0
- data/smoke/block10.rb +14 -0
- data/smoke/block11.rb +39 -0
- data/smoke/block12.rb +22 -0
- data/smoke/block2.rb +14 -0
- data/smoke/block3.rb +38 -0
- data/smoke/block4.rb +18 -0
- data/smoke/block5.rb +18 -0
- data/smoke/block6.rb +20 -0
- data/smoke/block7.rb +20 -0
- data/smoke/block8.rb +27 -0
- data/smoke/block9.rb +12 -0
- data/smoke/blown.rb +12 -0
- data/smoke/break1.rb +18 -0
- data/smoke/break2.rb +15 -0
- data/smoke/case.rb +16 -0
- data/smoke/case2.rb +17 -0
- data/smoke/class.rb +5 -0
- data/smoke/class_instance_var.rb +9 -0
- data/smoke/class_method.rb +25 -0
- data/smoke/class_method2.rb +21 -0
- data/smoke/class_method3.rb +27 -0
- data/smoke/constant1.rb +38 -0
- data/smoke/constant2.rb +33 -0
- data/smoke/constant3.rb +9 -0
- data/smoke/constant4.rb +11 -0
- data/smoke/context-sensitive1.rb +12 -0
- data/smoke/cvar.rb +28 -0
- data/smoke/cvar2.rb +17 -0
- data/smoke/demo.rb +80 -0
- data/smoke/demo1.rb +16 -0
- data/smoke/demo10.rb +20 -0
- data/smoke/demo11.rb +11 -0
- data/smoke/demo2.rb +14 -0
- data/smoke/demo3.rb +16 -0
- data/smoke/demo4.rb +27 -0
- data/smoke/demo5.rb +13 -0
- data/smoke/demo6.rb +21 -0
- data/smoke/demo7.rb +14 -0
- data/smoke/demo8.rb +18 -0
- data/smoke/demo9.rb +18 -0
- data/smoke/dummy-execution1.rb +14 -0
- data/smoke/dummy-execution2.rb +16 -0
- data/smoke/ensure1.rb +20 -0
- data/smoke/enumerator.rb +15 -0
- data/smoke/expandarray1.rb +22 -0
- data/smoke/expandarray2.rb +23 -0
- data/smoke/fib.rb +28 -0
- data/smoke/flow1.rb +16 -0
- data/smoke/flow2.rb +14 -0
- data/smoke/flow3.rb +14 -0
- data/smoke/flow4.rb +5 -0
- data/smoke/flow5.rb +19 -0
- data/smoke/flow6.rb +19 -0
- data/smoke/flow7.rb +26 -0
- data/smoke/for.rb +9 -0
- data/smoke/freeze.rb +11 -0
- data/smoke/function.rb +16 -0
- data/smoke/gvar.rb +13 -0
- data/smoke/hash-fetch.rb +27 -0
- data/smoke/hash1.rb +18 -0
- data/smoke/hash2.rb +12 -0
- data/smoke/hash3.rb +13 -0
- data/smoke/hash4.rb +10 -0
- data/smoke/hash5.rb +14 -0
- data/smoke/inheritance.rb +34 -0
- data/smoke/inheritance2.rb +29 -0
- data/smoke/initialize.rb +26 -0
- data/smoke/instance_eval.rb +18 -0
- data/smoke/int_times.rb +14 -0
- data/smoke/integer.rb +10 -0
- data/smoke/ivar.rb +29 -0
- data/smoke/ivar2.rb +30 -0
- data/smoke/kernel-class.rb +12 -0
- data/smoke/keyword1.rb +11 -0
- data/smoke/keyword2.rb +11 -0
- data/smoke/keyword3.rb +12 -0
- data/smoke/keyword4.rb +11 -0
- data/smoke/keyword5.rb +15 -0
- data/smoke/kwsplat1.rb +42 -0
- data/smoke/kwsplat2.rb +12 -0
- data/smoke/manual-rbs.rb +27 -0
- data/smoke/manual-rbs.rbs +3 -0
- data/smoke/manual-rbs2.rb +20 -0
- data/smoke/manual-rbs2.rbs +8 -0
- data/smoke/masgn1.rb +13 -0
- data/smoke/masgn2.rb +17 -0
- data/smoke/masgn3.rb +12 -0
- data/smoke/method_in_branch.rb +22 -0
- data/smoke/module1.rb +29 -0
- data/smoke/module2.rb +28 -0
- data/smoke/module3.rb +33 -0
- data/smoke/module4.rb +29 -0
- data/smoke/module_function1.rb +28 -0
- data/smoke/module_function2.rb +28 -0
- data/smoke/multiple-include.rb +14 -0
- data/smoke/multiple-superclass.rb +16 -0
- data/smoke/next1.rb +20 -0
- data/smoke/next2.rb +16 -0
- data/smoke/object-send1.rb +22 -0
- data/smoke/once.rb +12 -0
- data/smoke/optional1.rb +13 -0
- data/smoke/optional2.rb +15 -0
- data/smoke/parameterizedd-self.rb +18 -0
- data/smoke/pathname1.rb +13 -0
- data/smoke/pathname2.rb +13 -0
- data/smoke/printf.rb +20 -0
- data/smoke/proc.rb +19 -0
- data/smoke/proc2.rb +16 -0
- data/smoke/proc3.rb +14 -0
- data/smoke/proc4.rb +11 -0
- data/smoke/range.rb +13 -0
- data/smoke/redo1.rb +21 -0
- data/smoke/redo2.rb +22 -0
- data/smoke/req-keyword.rb +12 -0
- data/smoke/rescue1.rb +20 -0
- data/smoke/rescue2.rb +22 -0
- data/smoke/respond_to.rb +22 -0
- data/smoke/rest-farg.rb +10 -0
- data/smoke/rest1.rb +25 -0
- data/smoke/rest2.rb +30 -0
- data/smoke/rest3.rb +36 -0
- data/smoke/rest4.rb +18 -0
- data/smoke/rest5.rb +10 -0
- data/smoke/rest6.rb +11 -0
- data/smoke/retry1.rb +20 -0
- data/smoke/return.rb +13 -0
- data/smoke/reveal.rb +13 -0
- data/smoke/singleton_class.rb +8 -0
- data/smoke/singleton_method.rb +9 -0
- data/smoke/step.rb +17 -0
- data/smoke/string-split.rb +11 -0
- data/smoke/struct.rb +9 -0
- data/smoke/struct2.rb +24 -0
- data/smoke/super1.rb +50 -0
- data/smoke/super2.rb +16 -0
- data/smoke/super3.rb +19 -0
- data/smoke/svar1.rb +12 -0
- data/smoke/tap1.rb +17 -0
- data/smoke/toplevel.rb +12 -0
- data/smoke/two-map.rb +17 -0
- data/smoke/type_var.rb +10 -0
- data/smoke/typed_method.rb +15 -0
- data/smoke/union-recv.rb +29 -0
- data/smoke/variadic1.rb.notyet +5 -0
- data/smoke/wrong-extend.rb +25 -0
- data/smoke/wrong-include.rb +26 -0
- data/smoke/wrong-rbs.rb +15 -0
- data/smoke/wrong-rbs.rbs +7 -0
- data/testbed/ao.rb +297 -0
- data/testbed/diff-lcs-entrypoint.rb +4 -0
- data/testbed/goodcheck-Gemfile.lock +51 -0
- data/tools/coverage.rb +14 -0
- data/tools/setup-insns-def.rb +30 -0
- data/tools/stackprof-wrapper.rb +10 -0
- data/typeprof.gemspec +24 -0
- metadata +262 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
module TypeProf
|
|
2
|
+
module Utils
|
|
3
|
+
def self.array_update(ary, idx, elem)
|
|
4
|
+
idx %= ary.size
|
|
5
|
+
ary[0...idx] + [elem] + ary[idx+1..-1]
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
module StructuralEquality
|
|
9
|
+
def hash
|
|
10
|
+
@_hash ||=
|
|
11
|
+
begin
|
|
12
|
+
h = 0
|
|
13
|
+
instance_variables.each do |v|
|
|
14
|
+
h ^= instance_variable_get(v).hash if v != :@_hash
|
|
15
|
+
end
|
|
16
|
+
h
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
TABLE = {}
|
|
21
|
+
|
|
22
|
+
def self.included(klass)
|
|
23
|
+
def klass.new(*args)
|
|
24
|
+
(TABLE[self] ||= {})[args] ||= super
|
|
25
|
+
end
|
|
26
|
+
class << klass
|
|
27
|
+
ruby2_keywords :new
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class Set
|
|
33
|
+
include StructuralEquality
|
|
34
|
+
|
|
35
|
+
attr_reader :tbl
|
|
36
|
+
|
|
37
|
+
def self.[](*values)
|
|
38
|
+
tbl = {}
|
|
39
|
+
values.each do |v|
|
|
40
|
+
tbl[v] = true
|
|
41
|
+
end
|
|
42
|
+
new(tbl)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def initialize(tbl)
|
|
46
|
+
@tbl = tbl
|
|
47
|
+
@tbl.freeze
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def each(&blk)
|
|
51
|
+
@tbl.each_key(&blk)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
include Enumerable
|
|
55
|
+
|
|
56
|
+
def sum(other)
|
|
57
|
+
if @tbl.size == 0
|
|
58
|
+
other
|
|
59
|
+
elsif other.tbl.size == 0
|
|
60
|
+
self
|
|
61
|
+
else
|
|
62
|
+
Set.new(@tbl.merge(other.tbl))
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def add(new_val)
|
|
67
|
+
tbl = @tbl.dup
|
|
68
|
+
tbl[new_val] = true
|
|
69
|
+
Set.new(tbl)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def size
|
|
73
|
+
@tbl.size
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def map(&blk)
|
|
77
|
+
tbl = {}
|
|
78
|
+
each do |elem|
|
|
79
|
+
v = yield(elem)
|
|
80
|
+
tbl[v] = true
|
|
81
|
+
end
|
|
82
|
+
Set.new(tbl)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def inspect
|
|
86
|
+
s = []
|
|
87
|
+
each {|v| s << v.inspect }
|
|
88
|
+
"{#{ s.join(", ") }}"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def include?(elem)
|
|
92
|
+
@tbl[elem]
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def intersection(other)
|
|
96
|
+
tbl = {}
|
|
97
|
+
h = 0
|
|
98
|
+
each do |elem|
|
|
99
|
+
if other.include?(elem)
|
|
100
|
+
tbl << elem
|
|
101
|
+
h ^= elem.hash
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
Set.new(tbl, h)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
class MutableSet
|
|
109
|
+
def initialize(*values)
|
|
110
|
+
@hash = {}
|
|
111
|
+
values.each {|v| @hash[v] = v }
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def each(&blk)
|
|
115
|
+
@hash.each_key(&blk)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
include Enumerable
|
|
119
|
+
|
|
120
|
+
def <<(v)
|
|
121
|
+
@hash[v] = true
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def [](v)
|
|
125
|
+
@hash[v]
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def delete(v)
|
|
129
|
+
@hash.delete(v)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def inspect
|
|
133
|
+
s = []
|
|
134
|
+
each {|v| s << v.inspect }
|
|
135
|
+
"{#{ s.join(", ") }}"
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def size
|
|
139
|
+
@hash.size
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def to_set
|
|
143
|
+
Set[*@hash.keys]
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
class HashWrapper
|
|
148
|
+
include StructuralEquality
|
|
149
|
+
|
|
150
|
+
def initialize(hash)
|
|
151
|
+
@internal_hash = hash.freeze
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
attr_reader :internal_hash
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
class WorkList
|
|
158
|
+
def initialize
|
|
159
|
+
@heap = []
|
|
160
|
+
@set = MutableSet.new
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def insert(key, val)
|
|
164
|
+
i = @heap.size
|
|
165
|
+
@heap << [key, val]
|
|
166
|
+
while i > 0 && (@heap[i][0] <=> @heap[i / 2][0]) < 0
|
|
167
|
+
@heap[i], @heap[i / 2] = @heap[i / 2], @heap[i]
|
|
168
|
+
i /= 2
|
|
169
|
+
end
|
|
170
|
+
@set << val
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def member?(val)
|
|
174
|
+
@set[val]
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def deletemin
|
|
178
|
+
return nil if @heap.empty?
|
|
179
|
+
val = @heap[0][1]
|
|
180
|
+
@set.delete(val)
|
|
181
|
+
if @heap.size == 1
|
|
182
|
+
@heap.pop
|
|
183
|
+
return val
|
|
184
|
+
end
|
|
185
|
+
@heap[0] = @heap.pop
|
|
186
|
+
i = 0
|
|
187
|
+
while (j = i * 2 + 1) < @heap.size
|
|
188
|
+
j += 1 if j + 1 < @heap.size && (@heap[j][0] <=> @heap[j + 1][0]) >= 0
|
|
189
|
+
break if (@heap[i][0] <=> @heap[j][0]) < 0
|
|
190
|
+
@heap[i], @heap[j] = @heap[j], @heap[i]
|
|
191
|
+
i = j
|
|
192
|
+
end
|
|
193
|
+
return val
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def size
|
|
197
|
+
@heap.size
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def empty?
|
|
201
|
+
@heap.empty?
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def inspect
|
|
205
|
+
"#<#{ self.class }:#{ @heap.map {|_key, val| val }.inspect }>"
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
data/run.sh
ADDED
data/smoke/alias.rb
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
def foo(x)
|
|
2
|
+
x
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
alias bar foo
|
|
6
|
+
|
|
7
|
+
class Test
|
|
8
|
+
def baz(x)
|
|
9
|
+
x
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
alias qux baz
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
foo(1)
|
|
16
|
+
bar("str")
|
|
17
|
+
Test.new.baz(1)
|
|
18
|
+
Test.new.qux("str")
|
|
19
|
+
|
|
20
|
+
__END__
|
|
21
|
+
# Classes
|
|
22
|
+
class Object
|
|
23
|
+
def foo : (Integer) -> Integer
|
|
24
|
+
def bar : (String) -> String
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class Test
|
|
28
|
+
def baz : (Integer) -> Integer
|
|
29
|
+
def qux : (String) -> String
|
|
30
|
+
end
|
data/smoke/alias2.rb
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class Foo
|
|
2
|
+
class << self
|
|
3
|
+
alias [] new
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def initialize(a, b, c)
|
|
7
|
+
@a, @b, @c = a, b, c
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
Foo[:x, :y, :z]
|
|
12
|
+
__END__
|
|
13
|
+
# Classes
|
|
14
|
+
class Foo
|
|
15
|
+
@a : :x
|
|
16
|
+
@b : :y
|
|
17
|
+
@c : :z
|
|
18
|
+
def initialize : (:x, :y, :z) -> [:x, :y, :z]
|
|
19
|
+
end
|
data/smoke/any-cbase.rb
ADDED
data/smoke/any1.rb
ADDED
data/smoke/any2.rb
ADDED
data/smoke/arguments.rb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
def foo(x)
|
|
2
|
+
end
|
|
3
|
+
def bar(x)
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
bar(foo(1, 2))
|
|
7
|
+
|
|
8
|
+
__END__
|
|
9
|
+
# Errors
|
|
10
|
+
smoke/arguments.rb:6: [error] wrong number of arguments (given 2, expected 1)
|
|
11
|
+
|
|
12
|
+
# Classes
|
|
13
|
+
class Object
|
|
14
|
+
def foo : (untyped) -> nil
|
|
15
|
+
def bar : (untyped) -> nil
|
|
16
|
+
end
|
data/smoke/array-each.rb
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
def log(x)
|
|
2
|
+
end
|
|
3
|
+
|
|
4
|
+
[].each do |x|
|
|
5
|
+
# Currently, x is bot. But, [].each is rarely useful.
|
|
6
|
+
# It would be a good guess to assume a empty receiver of Array#each means a wrong guess.
|
|
7
|
+
# So, it would be good to assume x as any
|
|
8
|
+
log(x)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
__END__
|
|
12
|
+
# Classes
|
|
13
|
+
class Object
|
|
14
|
+
def log : (bot) -> nil
|
|
15
|
+
end
|
data/smoke/array-ltlt.rb
ADDED
data/smoke/array-map.rb
ADDED
data/smoke/array-map2.rb
ADDED
data/smoke/array-map3.rb
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
def map_test(a)
|
|
2
|
+
a.map {|n| n.to_s }
|
|
3
|
+
end
|
|
4
|
+
def map_bang_test(a)
|
|
5
|
+
a.map! {|n| n.to_s }
|
|
6
|
+
a
|
|
7
|
+
end
|
|
8
|
+
def map_bang_test_known_bug(a)
|
|
9
|
+
a.map! {|n| n.to_s }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
map_test([1, 2, 3])
|
|
13
|
+
map_bang_test([1, 2, 3])
|
|
14
|
+
map_bang_test_known_bug([1, 2, 3])
|
|
15
|
+
|
|
16
|
+
__END__
|
|
17
|
+
# Classes
|
|
18
|
+
class Object
|
|
19
|
+
def map_test : ([Integer, Integer, Integer]) -> Array[String]
|
|
20
|
+
def map_bang_test : ([Integer, Integer, Integer]) -> (Array[Integer | String])
|
|
21
|
+
def map_bang_test_known_bug : ([Integer, Integer, Integer]) -> [Integer, Integer, Integer]
|
|
22
|
+
end
|