typeprof 0.5.3 → 0.8.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 +6 -4
- data/doc/doc.ja.md +3 -4
- data/doc/doc.md +3 -4
- data/lib/typeprof/analyzer.rb +248 -166
- data/lib/typeprof/arguments.rb +12 -6
- data/lib/typeprof/builtin.rb +123 -23
- data/lib/typeprof/cli.rb +33 -34
- data/lib/typeprof/config.rb +6 -4
- data/lib/typeprof/container-type.rb +175 -112
- data/lib/typeprof/export.rb +23 -17
- data/lib/typeprof/import.rb +58 -53
- data/lib/typeprof/method.rb +59 -125
- data/lib/typeprof/type.rb +26 -14
- data/lib/typeprof/version.rb +1 -1
- data/smoke/alias.rb +1 -0
- data/smoke/any1.rb +1 -0
- data/smoke/any2.rb +1 -0
- data/smoke/arguments.rb +1 -0
- data/smoke/arguments2.rb +1 -0
- data/smoke/array-each.rb +1 -0
- data/smoke/array-each2.rb +1 -0
- data/smoke/array-each3.rb +2 -1
- data/smoke/array-ltlt.rb +1 -0
- data/smoke/array-ltlt2.rb +1 -0
- data/smoke/array-map.rb +1 -0
- data/smoke/array-map2.rb +1 -0
- data/smoke/array-map3.rb +1 -0
- data/smoke/array-mul.rb +1 -0
- data/smoke/array-plus1.rb +1 -0
- data/smoke/array-pop.rb +1 -0
- data/smoke/array-range-aref.rb +71 -0
- data/smoke/array-replace.rb +1 -0
- data/smoke/array-s-aref.rb +1 -0
- data/smoke/array1.rb +1 -0
- data/smoke/array10.rb +1 -0
- data/smoke/array11.rb +2 -1
- data/smoke/array12.rb +1 -0
- data/smoke/array13.rb +1 -0
- data/smoke/array14.rb +1 -0
- data/smoke/array2.rb +1 -0
- data/smoke/array4.rb +1 -0
- data/smoke/array5.rb +1 -0
- data/smoke/array6.rb +3 -2
- data/smoke/array7.rb +1 -0
- data/smoke/array8.rb +1 -1
- data/smoke/array9.rb +1 -0
- data/smoke/autoload.rb +14 -0
- data/smoke/backtrace.rb +1 -0
- data/smoke/block-ambiguous.rb +1 -0
- data/smoke/block-args1-rest.rb +1 -0
- data/smoke/block-args1.rb +1 -0
- data/smoke/block-args2-rest.rb +1 -0
- data/smoke/block-args2.rb +4 -3
- data/smoke/block-args3-rest.rb +1 -0
- data/smoke/block-args3.rb +5 -4
- data/smoke/block-blockarg.rb +2 -1
- data/smoke/block-kwarg.rb +1 -0
- data/smoke/block1.rb +1 -0
- data/smoke/block10.rb +1 -0
- data/smoke/block11.rb +1 -0
- data/smoke/block12.rb +1 -0
- data/smoke/block14.rb +1 -0
- data/smoke/block2.rb +1 -0
- data/smoke/block4.rb +1 -0
- data/smoke/block5.rb +2 -1
- data/smoke/block6.rb +1 -0
- data/smoke/block7.rb +1 -0
- data/smoke/block8.rb +1 -0
- data/smoke/block9.rb +1 -0
- data/smoke/blown.rb +1 -0
- data/smoke/break1.rb +1 -0
- data/smoke/break2.rb +1 -0
- data/smoke/case.rb +1 -0
- data/smoke/case2.rb +1 -0
- data/smoke/class_method3.rb +2 -0
- data/smoke/constant2.rb +2 -2
- data/smoke/constant3.rb +1 -0
- data/smoke/constant4.rb +1 -0
- data/smoke/context-sensitive1.rb +1 -0
- data/smoke/cvar.rb +1 -0
- data/smoke/define_method.rb +16 -0
- data/smoke/define_method2.rb +18 -0
- data/smoke/demo.rb +1 -0
- data/smoke/demo1.rb +1 -0
- data/smoke/demo10.rb +1 -0
- data/smoke/demo11.rb +1 -0
- data/smoke/demo2.rb +1 -0
- data/smoke/demo3.rb +1 -0
- data/smoke/demo5.rb +1 -1
- data/smoke/demo7.rb +1 -0
- data/smoke/demo8.rb +1 -0
- data/smoke/demo9.rb +2 -1
- data/smoke/dummy-execution1.rb +1 -0
- data/smoke/ensure1.rb +1 -0
- data/smoke/enumerator.rb +1 -0
- data/smoke/expandarray1.rb +1 -0
- data/smoke/expandarray2.rb +1 -0
- data/smoke/flow1.rb +1 -0
- data/smoke/flow2.rb +1 -0
- data/smoke/flow3.rb +1 -0
- data/smoke/flow5.rb +1 -0
- data/smoke/flow6.rb +1 -0
- data/smoke/flow7.rb +1 -0
- data/smoke/flow8.rb +1 -0
- data/smoke/freeze.rb +1 -0
- data/smoke/function.rb +1 -0
- data/smoke/gvar.rb +1 -0
- data/smoke/gvar2.rb +1 -0
- data/smoke/hash-fetch.rb +1 -0
- data/smoke/hash-merge-bang.rb +1 -0
- data/smoke/hash1.rb +3 -1
- data/smoke/hash2.rb +1 -0
- data/smoke/hash3.rb +1 -0
- data/smoke/hash4.rb +2 -1
- data/smoke/inheritance2.rb +2 -2
- data/smoke/initialize.rb +1 -0
- data/smoke/int_times.rb +1 -0
- data/smoke/integer.rb +1 -0
- data/smoke/ivar.rb +1 -0
- data/smoke/ivar2.rb +1 -1
- data/smoke/kernel-class.rb +2 -1
- data/smoke/keyword1.rb +1 -0
- data/smoke/keyword2.rb +1 -0
- data/smoke/keyword3.rb +1 -0
- data/smoke/keyword4.rb +1 -0
- data/smoke/keyword5.rb +1 -0
- data/smoke/kwrest.rb +12 -0
- data/smoke/kwrest.rbs +3 -0
- data/smoke/kwsplat1.rb +2 -1
- data/smoke/kwsplat2.rb +1 -0
- data/smoke/manual-rbs.rb +1 -0
- data/smoke/manual-rbs2.rb +1 -0
- data/smoke/masgn1.rb +1 -0
- data/smoke/masgn2.rb +1 -0
- data/smoke/masgn3.rb +1 -0
- data/smoke/method_in_branch.rb +1 -0
- data/smoke/method_missing.rb +28 -0
- data/smoke/multiple-superclass.rb +1 -1
- data/smoke/next1.rb +1 -0
- data/smoke/next2.rb +1 -0
- data/smoke/object-send1.rb +1 -0
- data/smoke/once.rb +1 -0
- data/smoke/optional1.rb +1 -0
- data/smoke/optional2.rb +1 -0
- data/smoke/optional3.rb +1 -0
- data/smoke/parameterizedd-self.rb +3 -2
- data/smoke/parameterizedd-self2.rb +15 -0
- data/smoke/pathname1.rb +1 -0
- data/smoke/pathname2.rb +1 -0
- data/smoke/pattern-match1.rb +1 -0
- data/smoke/pattern-match2.rb +1 -0
- data/smoke/proc.rb +1 -0
- data/smoke/proc2.rb +1 -0
- data/smoke/proc3.rb +1 -0
- data/smoke/proc4.rb +1 -0
- data/smoke/range.rb +1 -0
- data/smoke/rbs-alias.rb +1 -0
- data/smoke/rbs-attr.rb +3 -2
- data/smoke/rbs-attr2.rb +11 -0
- data/smoke/rbs-attr2.rbs +3 -0
- data/smoke/rbs-extend.rb +1 -0
- data/smoke/rbs-interface.rb +1 -0
- data/smoke/rbs-proc1.rb +1 -0
- data/smoke/rbs-proc2.rb +1 -0
- data/smoke/rbs-proc3.rb +1 -0
- data/smoke/rbs-record.rb +1 -0
- data/smoke/rbs-tyvar.rb +1 -0
- data/smoke/rbs-tyvar2.rb +1 -0
- data/smoke/rbs-tyvar3.rb +1 -0
- data/smoke/rbs-tyvar5.rb +1 -0
- data/smoke/rbs-tyvar6.rb +18 -0
- data/smoke/rbs-tyvar6.rbs +12 -0
- data/smoke/rbs-tyvar7.rb +12 -0
- data/smoke/rbs-tyvar7.rbs +7 -0
- data/smoke/rbs-vars.rb +1 -2
- data/smoke/redo1.rb +1 -0
- data/smoke/redo2.rb +1 -0
- data/smoke/req-keyword.rb +1 -0
- data/smoke/rescue1.rb +1 -0
- data/smoke/rescue2.rb +1 -0
- data/smoke/respond_to.rb +1 -0
- data/smoke/rest-farg.rb +1 -0
- data/smoke/rest1.rb +1 -0
- data/smoke/rest2.rb +1 -0
- data/smoke/rest3.rb +1 -0
- data/smoke/rest4.rb +1 -0
- data/smoke/rest5.rb +1 -0
- data/smoke/rest6.rb +1 -0
- data/smoke/retry1.rb +1 -0
- data/smoke/return.rb +1 -0
- data/smoke/step.rb +1 -0
- data/smoke/string-split.rb +1 -0
- data/smoke/struct.rb +2 -2
- data/smoke/struct2.rb +1 -0
- data/smoke/super1.rb +1 -0
- data/smoke/super4.rb +43 -0
- data/smoke/super5.rb +36 -0
- data/smoke/svar1.rb +1 -0
- data/smoke/symbol-proc.rb +1 -0
- data/smoke/tap1.rb +1 -0
- data/smoke/toplevel.rb +1 -0
- data/smoke/two-map.rb +1 -0
- data/smoke/type_var.rb +1 -0
- data/smoke/typed_method.rb +1 -0
- data/smoke/uninitialize-var.rb +1 -0
- data/smoke/union-recv.rb +2 -2
- metadata +18 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dd38b5e501a5d4fbe4db1ad43015c44ab39dbfefc3f7638516faeb5bcafd21a9
|
|
4
|
+
data.tar.gz: 000f140ab750e4ddd57863851c21a830bfe470c0eb7be9e38442ca535f4ef041
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '00924963d5f91c4609224615507fcfb240a140c8119bf76f24aa28973342e6b61c528fc579781690f9f0392bf0d125c8bdb70499525791603c111ed9251da931'
|
|
7
|
+
data.tar.gz: ee07e0636cd3e26271c468e1927e676a1b320ddefe13dc2412c254cac9aaeac7ca5db1936a26ccc477c2494473fde1d2bdde7a28bd1fa384c6995d7ae4d085ea
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
typeprof (0.
|
|
4
|
+
typeprof (0.8.0)
|
|
5
5
|
rbs (>= 0.17.0)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
@@ -11,13 +11,15 @@ GEM
|
|
|
11
11
|
docile (1.3.2)
|
|
12
12
|
power_assert (1.2.0)
|
|
13
13
|
rake (13.0.1)
|
|
14
|
-
rbs (0.
|
|
15
|
-
simplecov (0.
|
|
14
|
+
rbs (0.18.1)
|
|
15
|
+
simplecov (0.20.0)
|
|
16
16
|
docile (~> 1.1)
|
|
17
17
|
simplecov-html (~> 0.11)
|
|
18
|
+
simplecov_json_formatter (~> 0.1)
|
|
18
19
|
simplecov-html (0.12.3)
|
|
20
|
+
simplecov_json_formatter (0.1.2)
|
|
19
21
|
stackprof (0.2.16)
|
|
20
|
-
test-unit (3.3.
|
|
22
|
+
test-unit (3.3.7)
|
|
21
23
|
power_assert
|
|
22
24
|
|
|
23
25
|
PLATFORMS
|
data/doc/doc.ja.md
CHANGED
|
@@ -35,10 +35,9 @@ $ typeprof sig/app.rbs app.rb -o sig/app.gen.rbs
|
|
|
35
35
|
* `--exclude-dir DIR`: `DIR`以下のファイルの解析結果を出力から省略する。後に指定されているほうが優先される(`--include-dir foo --exclude-dir foo/bar`の場合う、foo/bar/baz.rbの結果は出力されず、foo/baz.rbの結果は出力される)。
|
|
36
36
|
* `--include-dir DIR`: `DIR`以下のファイルの解析結果を出力に含める。後に指定されているほうが優先される(`--exclude-dir foo --include-dir foo/bar`の場合、
|
|
37
37
|
foo/bar/baz.rbの結果は出力されるが、foo/baz.rbの結果は出力されない)。
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* `-ftype-depth-limit=NUM`: (後で書く)
|
|
38
|
+
* `--show-errors`: 実行中に見つけたバグの可能性を出力します(多くの場合、大量のfalse positiveが出ます)。
|
|
39
|
+
* `--show-untyped`: デフォルトでは`A | untyped`と推定されたところを単に`A`と出力しますが、より生の出力、つまり`A | untyped`と出力します。
|
|
40
|
+
* `--type-depth-limit=NUM`: (後で書く)
|
|
42
41
|
|
|
43
42
|
## TypeProfとは
|
|
44
43
|
|
data/doc/doc.md
CHANGED
|
@@ -34,10 +34,9 @@ Here is a list of currently avaiable options:
|
|
|
34
34
|
* `-r GEMNAME`: Load the RBS files of `GEMNAME`
|
|
35
35
|
* `--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.)
|
|
36
36
|
* `--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.)
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* `-ftype-depth-limit=NUM`: (undocumented yet)
|
|
37
|
+
* `--show-errors`: Prints out possible bugs found during execution (often a lot of false positives).
|
|
38
|
+
* `--show-untyped`: When TypeProf infers a type `A | untyped`, it simply outputs `A` by default. But this option forces to output `A | untyped`.
|
|
39
|
+
* `--type-depth-limit=NUM`: (undocumented yet)
|
|
41
40
|
|
|
42
41
|
## What is a TypeProf?
|
|
43
42
|
|
data/lib/typeprof/analyzer.rb
CHANGED
|
@@ -83,10 +83,11 @@ module TypeProf
|
|
|
83
83
|
class StaticEnv
|
|
84
84
|
include Utils::StructuralEquality
|
|
85
85
|
|
|
86
|
-
def initialize(recv_ty, blk_ty, mod_func)
|
|
86
|
+
def initialize(recv_ty, blk_ty, mod_func, pub_meth)
|
|
87
87
|
@recv_ty = recv_ty
|
|
88
88
|
@blk_ty = blk_ty
|
|
89
89
|
@mod_func = mod_func
|
|
90
|
+
@pub_meth = pub_meth
|
|
90
91
|
|
|
91
92
|
return if recv_ty == :top #OK
|
|
92
93
|
recv_ty.each_child_global do |ty|
|
|
@@ -94,13 +95,14 @@ module TypeProf
|
|
|
94
95
|
end
|
|
95
96
|
end
|
|
96
97
|
|
|
97
|
-
attr_reader :recv_ty, :blk_ty, :mod_func
|
|
98
|
+
attr_reader :recv_ty, :blk_ty, :mod_func, :pub_meth
|
|
98
99
|
|
|
99
100
|
def merge(other)
|
|
100
101
|
recv_ty = @recv_ty.union(other.recv_ty)
|
|
101
102
|
blk_ty = @blk_ty.union(other.blk_ty)
|
|
102
103
|
mod_func = @mod_func & other.mod_func # ??
|
|
103
|
-
|
|
104
|
+
pub_meth = @pub_meth & other.pub_meth # ??
|
|
105
|
+
StaticEnv.new(recv_ty, blk_ty, mod_func, pub_meth)
|
|
104
106
|
end
|
|
105
107
|
end
|
|
106
108
|
|
|
@@ -185,29 +187,27 @@ module TypeProf
|
|
|
185
187
|
Env.new(@static_env, Utils.array_update(@locals, idx, ty), @stack, @type_params)
|
|
186
188
|
end
|
|
187
189
|
|
|
188
|
-
def deploy_type(klass, alloc_site, elems, base_ty)
|
|
189
|
-
local_ty = klass.new(alloc_site, base_ty)
|
|
190
|
-
type_params = Utils::HashWrapper.new(@type_params.internal_hash.merge({ alloc_site => elems }))
|
|
191
|
-
nenv = Env.new(@static_env, @locals, @stack, type_params)
|
|
192
|
-
return nenv, local_ty
|
|
193
|
-
end
|
|
194
|
-
|
|
195
190
|
def get_container_elem_types(id)
|
|
196
191
|
@type_params.internal_hash[id]
|
|
197
192
|
end
|
|
198
193
|
|
|
199
|
-
def
|
|
194
|
+
def deploy_type(id, elems)
|
|
200
195
|
type_params = Utils::HashWrapper.new(@type_params.internal_hash.merge({ id => elems }))
|
|
201
196
|
Env.new(@static_env, @locals, @stack, type_params)
|
|
202
197
|
end
|
|
203
198
|
|
|
204
199
|
def enable_module_function
|
|
205
|
-
senv = StaticEnv.new(@static_env.recv_ty, @static_env.blk_ty, true)
|
|
200
|
+
senv = StaticEnv.new(@static_env.recv_ty, @static_env.blk_ty, true, @static_env.pub_meth)
|
|
201
|
+
Env.new(senv, @locals, @stack, @type_params)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def method_public_set(flag)
|
|
205
|
+
senv = StaticEnv.new(@static_env.recv_ty, @static_env.blk_ty, @static_env.mod_func, flag)
|
|
206
206
|
Env.new(senv, @locals, @stack, @type_params)
|
|
207
207
|
end
|
|
208
208
|
|
|
209
209
|
def replace_recv_ty(ty)
|
|
210
|
-
senv = StaticEnv.new(ty, @static_env.blk_ty, @static_env.mod_func)
|
|
210
|
+
senv = StaticEnv.new(ty, @static_env.blk_ty, @static_env.mod_func, @static_env.pub_meth)
|
|
211
211
|
Env.new(senv, @locals, @stack, @type_params)
|
|
212
212
|
end
|
|
213
213
|
|
|
@@ -252,6 +252,8 @@ module TypeProf
|
|
|
252
252
|
@rbs_reader = RBSReader.new
|
|
253
253
|
|
|
254
254
|
@terminated = false
|
|
255
|
+
|
|
256
|
+
@anonymous_struct_gen_id = 0
|
|
255
257
|
end
|
|
256
258
|
|
|
257
259
|
attr_reader :return_envs, :loaded_features, :rbs_reader
|
|
@@ -279,11 +281,10 @@ module TypeProf
|
|
|
279
281
|
attr_reader :class_defs
|
|
280
282
|
|
|
281
283
|
class ClassDef # or ModuleDef
|
|
282
|
-
def initialize(kind, name,
|
|
284
|
+
def initialize(kind, name, absolute_path)
|
|
283
285
|
raise unless name.is_a?(Array)
|
|
284
286
|
@kind = kind
|
|
285
|
-
@
|
|
286
|
-
@modules = { true => {}, false => {} }
|
|
287
|
+
@modules = { true => [], false => [] }
|
|
287
288
|
@name = name
|
|
288
289
|
@consts = {}
|
|
289
290
|
@methods = {}
|
|
@@ -293,14 +294,16 @@ module TypeProf
|
|
|
293
294
|
@namespace = nil
|
|
294
295
|
end
|
|
295
296
|
|
|
296
|
-
attr_reader :kind, :
|
|
297
|
+
attr_reader :kind, :modules, :consts, :methods, :ivars, :cvars, :absolute_path
|
|
297
298
|
attr_accessor :name, :klass_obj
|
|
298
299
|
|
|
299
|
-
def include_module(mod, singleton, absolute_path)
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
300
|
+
def include_module(mod, type_args, singleton, absolute_path)
|
|
301
|
+
module_type_args, _, absolute_paths = @modules[singleton].find {|m,| m == mod }
|
|
302
|
+
if module_type_args
|
|
303
|
+
raise "inconsistent include/extend type args in RBS?" if module_type_args != type_args && type_args != [] && type_args != nil
|
|
304
|
+
else
|
|
305
|
+
absolute_paths = Utils::MutableSet.new
|
|
306
|
+
@modules[singleton].unshift([mod, type_args, absolute_paths])
|
|
304
307
|
end
|
|
305
308
|
absolute_paths << absolute_path
|
|
306
309
|
end
|
|
@@ -317,13 +320,26 @@ module TypeProf
|
|
|
317
320
|
@consts[name] = [ty, absolute_path]
|
|
318
321
|
end
|
|
319
322
|
|
|
320
|
-
def
|
|
321
|
-
@methods[[singleton, mid]]
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
323
|
+
def adjust_substitution(singleton, mid, mthd, subst, direct, &blk)
|
|
324
|
+
mthds = @methods[[singleton, mid]]
|
|
325
|
+
yield subst, direct if mthds&.include?(mthd)
|
|
326
|
+
@modules[singleton].each do |mod_def, type_args,|
|
|
327
|
+
if mod_def.klass_obj.type_params && type_args
|
|
328
|
+
subst2 = {}
|
|
329
|
+
mod_def.klass_obj.type_params.zip(type_args) do |(tyvar, *), tyarg|
|
|
330
|
+
tyvar = Type::Var.new(tyvar)
|
|
331
|
+
subst2[tyvar] = tyarg.substitute(subst, Config.options[:type_depth_limit])
|
|
332
|
+
end
|
|
333
|
+
mod_def.adjust_substitution(false, mid, mthd, subst2, false, &blk)
|
|
325
334
|
end
|
|
326
|
-
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
def search_method(singleton, mid, &blk)
|
|
339
|
+
mthds = @methods[[singleton, mid]]
|
|
340
|
+
yield mthds, @klass_obj, singleton if mthds
|
|
341
|
+
@modules[singleton].each do |mod_def,|
|
|
342
|
+
mod_def.search_method(false, mid, &blk)
|
|
327
343
|
end
|
|
328
344
|
end
|
|
329
345
|
|
|
@@ -342,12 +358,16 @@ module TypeProf
|
|
|
342
358
|
end
|
|
343
359
|
|
|
344
360
|
def set_method(mid, singleton, mdef)
|
|
345
|
-
|
|
346
|
-
|
|
361
|
+
if mdef
|
|
362
|
+
@methods[[singleton, mid]] = Utils::MutableSet.new
|
|
363
|
+
@methods[[singleton, mid]] << mdef
|
|
364
|
+
else
|
|
365
|
+
@methods.delete([singleton, mid])
|
|
366
|
+
end
|
|
347
367
|
end
|
|
348
368
|
end
|
|
349
369
|
|
|
350
|
-
def include_module(including_mod, included_mod, singleton, absolute_path)
|
|
370
|
+
def include_module(including_mod, included_mod, type_args, singleton, absolute_path)
|
|
351
371
|
return if included_mod == Type.any
|
|
352
372
|
|
|
353
373
|
including_mod = @class_defs[including_mod.idx]
|
|
@@ -355,7 +375,7 @@ module TypeProf
|
|
|
355
375
|
if included_mod.is_a?(Type::Class)
|
|
356
376
|
included_mod = @class_defs[included_mod.idx]
|
|
357
377
|
if included_mod && included_mod.kind == :module
|
|
358
|
-
including_mod.include_module(included_mod, singleton, absolute_path)
|
|
378
|
+
including_mod.include_module(included_mod, type_args, singleton, absolute_path)
|
|
359
379
|
else
|
|
360
380
|
warn "including something that is not a module"
|
|
361
381
|
end
|
|
@@ -371,12 +391,7 @@ module TypeProf
|
|
|
371
391
|
show_name = cbase_path(cbase) + [name]
|
|
372
392
|
idx = @class_defs.size
|
|
373
393
|
if superclass
|
|
374
|
-
|
|
375
|
-
superclass_idx = superclass = nil
|
|
376
|
-
else
|
|
377
|
-
superclass_idx = superclass.idx
|
|
378
|
-
end
|
|
379
|
-
@class_defs[idx] = ClassDef.new(:class, show_name, superclass_idx, absolute_path)
|
|
394
|
+
@class_defs[idx] = ClassDef.new(:class, show_name, absolute_path)
|
|
380
395
|
klass = Type::Class.new(:class, idx, type_params, superclass, show_name)
|
|
381
396
|
@class_defs[idx].klass_obj = klass
|
|
382
397
|
cbase ||= klass # for bootstrap
|
|
@@ -384,7 +399,7 @@ module TypeProf
|
|
|
384
399
|
return klass
|
|
385
400
|
else
|
|
386
401
|
# module
|
|
387
|
-
@class_defs[idx] = ClassDef.new(:module, show_name,
|
|
402
|
+
@class_defs[idx] = ClassDef.new(:module, show_name, absolute_path)
|
|
388
403
|
mod = Type::Class.new(:module, idx, type_params, nil, show_name)
|
|
389
404
|
@class_defs[idx].klass_obj = mod
|
|
390
405
|
add_constant(cbase, name, mod, absolute_path)
|
|
@@ -392,13 +407,19 @@ module TypeProf
|
|
|
392
407
|
end
|
|
393
408
|
end
|
|
394
409
|
|
|
410
|
+
def add_superclass_type_args!(klass, tyargs)
|
|
411
|
+
klass.superclass_type_args = tyargs
|
|
412
|
+
end
|
|
413
|
+
|
|
395
414
|
def new_struct(ep)
|
|
396
415
|
return @struct_defs[ep] if @struct_defs[ep]
|
|
397
416
|
|
|
398
417
|
idx = @class_defs.size
|
|
399
418
|
superclass = Type::Builtin[:struct]
|
|
400
|
-
|
|
401
|
-
|
|
419
|
+
name = "AnonymousStruct_generated_#{ @anonymous_struct_gen_id += 1 }"
|
|
420
|
+
@class_defs[idx] = ClassDef.new(:class, [name], ep.ctx.iseq.absolute_path)
|
|
421
|
+
klass = Type::Class.new(:class, idx, [], superclass, name)
|
|
422
|
+
add_superclass_type_args!(klass, [Type.any])
|
|
402
423
|
@class_defs[idx].klass_obj = klass
|
|
403
424
|
|
|
404
425
|
@struct_defs[ep] = klass
|
|
@@ -428,28 +449,77 @@ module TypeProf
|
|
|
428
449
|
end
|
|
429
450
|
end
|
|
430
451
|
|
|
452
|
+
def adjust_substitution(klass, singleton, mid, mthd, subst, &blk)
|
|
453
|
+
direct = true
|
|
454
|
+
if klass.kind == :class
|
|
455
|
+
while klass != :__root__
|
|
456
|
+
class_def = @class_defs[klass.idx]
|
|
457
|
+
class_def.adjust_substitution(singleton, mid, mthd, subst, direct, &blk)
|
|
458
|
+
direct = false
|
|
459
|
+
if klass.superclass && klass.superclass_type_args
|
|
460
|
+
subst2 = {}
|
|
461
|
+
klass.superclass.type_params.zip(klass.superclass_type_args) do |(tyvar, *), tyarg|
|
|
462
|
+
tyvar = Type::Var.new(tyvar)
|
|
463
|
+
subst2[tyvar] = tyarg.substitute(subst, Config.options[:type_depth_limit])
|
|
464
|
+
end
|
|
465
|
+
subst = subst2
|
|
466
|
+
end
|
|
467
|
+
klass = klass.superclass
|
|
468
|
+
end
|
|
469
|
+
else
|
|
470
|
+
# module
|
|
471
|
+
class_def = @class_defs[klass.idx]
|
|
472
|
+
class_def.adjust_substitution(singleton, mid, mthd, subst, direct, &blk)
|
|
473
|
+
end
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
def search_method(klass, singleton, mid, &blk)
|
|
477
|
+
# XXX: support method alias correctly
|
|
478
|
+
klass_orig = klass
|
|
479
|
+
if klass.kind == :class
|
|
480
|
+
while klass != :__root__
|
|
481
|
+
class_def = @class_defs[klass.idx]
|
|
482
|
+
class_def.search_method(singleton, mid, &blk)
|
|
483
|
+
klass = klass.superclass
|
|
484
|
+
end
|
|
485
|
+
else
|
|
486
|
+
# module
|
|
487
|
+
class_def = @class_defs[klass.idx]
|
|
488
|
+
class_def.search_method(singleton, mid, &blk)
|
|
489
|
+
end
|
|
490
|
+
if singleton
|
|
491
|
+
search_method(Type::Builtin[klass_orig.kind], false, mid, &blk)
|
|
492
|
+
end
|
|
493
|
+
end
|
|
494
|
+
|
|
431
495
|
def get_method(klass, singleton, mid)
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
496
|
+
search_method(klass, singleton, mid) {|mthds,| return mthds }
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
def get_all_super_methods(klass, singleton, current_klass, mid)
|
|
500
|
+
hit = false
|
|
501
|
+
search_method(klass, singleton, mid) do |mthds, klass0, singleton0|
|
|
502
|
+
yield mthds, klass0, singleton0 if hit
|
|
503
|
+
hit = klass0 == current_klass
|
|
439
504
|
end
|
|
440
|
-
return get_method(Type::Builtin[:class], false, mid) if singleton
|
|
441
|
-
nil
|
|
442
505
|
end
|
|
443
506
|
|
|
444
507
|
def get_super_method(ctx, singleton)
|
|
445
|
-
|
|
508
|
+
klass = ctx.cref.klass
|
|
446
509
|
mid = ctx.mid
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
510
|
+
if klass.kind == :class
|
|
511
|
+
klass = klass.superclass
|
|
512
|
+
while klass != :__root__
|
|
513
|
+
class_def = @class_defs[klass.idx]
|
|
514
|
+
mthd = class_def.get_method(mid, singleton)
|
|
515
|
+
return mthd if mthd
|
|
516
|
+
klass = klass.superclass
|
|
517
|
+
end
|
|
518
|
+
else
|
|
519
|
+
# module
|
|
520
|
+
class_def = @class_defs[klass.idx]
|
|
450
521
|
mthd = class_def.get_method(mid, singleton)
|
|
451
522
|
return mthd if mthd
|
|
452
|
-
idx = class_def.superclass
|
|
453
523
|
end
|
|
454
524
|
nil
|
|
455
525
|
end
|
|
@@ -505,12 +575,12 @@ module TypeProf
|
|
|
505
575
|
end
|
|
506
576
|
end
|
|
507
577
|
|
|
508
|
-
def add_iseq_method(klass, mid, iseq, cref)
|
|
509
|
-
add_method(klass, mid, false, ISeqMethodDef.new(iseq, cref))
|
|
578
|
+
def add_iseq_method(klass, mid, iseq, cref, outer_ep, pub_meth)
|
|
579
|
+
add_method(klass, mid, false, ISeqMethodDef.new(iseq, cref, outer_ep, pub_meth))
|
|
510
580
|
end
|
|
511
581
|
|
|
512
|
-
def add_singleton_iseq_method(klass, mid, iseq, cref)
|
|
513
|
-
add_method(klass, mid, true, ISeqMethodDef.new(iseq, cref))
|
|
582
|
+
def add_singleton_iseq_method(klass, mid, iseq, cref, outer_ep, pub_meth)
|
|
583
|
+
add_method(klass, mid, true, ISeqMethodDef.new(iseq, cref, outer_ep, pub_meth))
|
|
514
584
|
end
|
|
515
585
|
|
|
516
586
|
def set_custom_method(klass, mid, impl)
|
|
@@ -719,7 +789,7 @@ module TypeProf
|
|
|
719
789
|
merge_return_env(tmp_ep) do |menv|
|
|
720
790
|
elems = menv.get_container_elem_types(id)
|
|
721
791
|
elems = yield elems
|
|
722
|
-
menv = menv.
|
|
792
|
+
menv = menv.deploy_type(id, elems)
|
|
723
793
|
gid = @alloc_site_to_global_id[id]
|
|
724
794
|
if gid
|
|
725
795
|
ty = globalize_type(elems.to_local_type(id, base_type), env, ep)
|
|
@@ -731,7 +801,7 @@ module TypeProf
|
|
|
731
801
|
else
|
|
732
802
|
elems = env.get_container_elem_types(id)
|
|
733
803
|
elems = yield elems
|
|
734
|
-
env = env.
|
|
804
|
+
env = env.deploy_type(id, elems)
|
|
735
805
|
gid = @alloc_site_to_global_id[id]
|
|
736
806
|
if gid
|
|
737
807
|
ty = globalize_type(elems.to_local_type(id, base_type), env, ep)
|
|
@@ -772,11 +842,11 @@ module TypeProf
|
|
|
772
842
|
ep = @worklist.deletemin
|
|
773
843
|
|
|
774
844
|
iter_counter += 1
|
|
775
|
-
if Config.
|
|
845
|
+
if Config.options[:show_indicator]
|
|
776
846
|
tick2 = Time.now
|
|
777
847
|
if tick2 - tick >= 1
|
|
778
848
|
tick = tick2
|
|
779
|
-
$stderr << "\rType Profiling... (%d
|
|
849
|
+
$stderr << "\rType Profiling... (%d instructions @ %s)\e[K" % [iter_counter, ep.source_location]
|
|
780
850
|
$stderr.flush
|
|
781
851
|
end
|
|
782
852
|
end
|
|
@@ -792,9 +862,7 @@ module TypeProf
|
|
|
792
862
|
|
|
793
863
|
break if @terminated
|
|
794
864
|
|
|
795
|
-
|
|
796
|
-
# It should work as a bit smarter "rbs prototype rb";
|
|
797
|
-
# show all method definitions as "untyped" arguments and return values
|
|
865
|
+
break unless Config.options[:stub_execution]
|
|
798
866
|
|
|
799
867
|
begin
|
|
800
868
|
iseq, (kind, dummy_continuation) = @pending_execution.first
|
|
@@ -819,7 +887,7 @@ module TypeProf
|
|
|
819
887
|
end
|
|
820
888
|
end
|
|
821
889
|
end
|
|
822
|
-
$stderr.print "\r\e[K" if Config.
|
|
890
|
+
$stderr.print "\r\e[K" if Config.options[:show_indicator]
|
|
823
891
|
|
|
824
892
|
stat_eps
|
|
825
893
|
end
|
|
@@ -860,9 +928,9 @@ module TypeProf
|
|
|
860
928
|
end
|
|
861
929
|
end
|
|
862
930
|
|
|
863
|
-
def pend_method_execution(iseq, meth, recv, mid, cref)
|
|
931
|
+
def pend_method_execution(iseq, meth, recv, mid, cref, ep)
|
|
864
932
|
ctx = Context.new(iseq, cref, mid)
|
|
865
|
-
ep = ExecutionPoint.new(ctx, 0,
|
|
933
|
+
ep = ExecutionPoint.new(ctx, 0, ep)
|
|
866
934
|
locals = [Type.nil] * iseq.locals.size
|
|
867
935
|
|
|
868
936
|
fargs_format = iseq.fargs_format
|
|
@@ -897,9 +965,11 @@ module TypeProf
|
|
|
897
965
|
locals[kwrest_index] = Type.any if kwrest_index
|
|
898
966
|
locals[block_index] = Type.nil if block_index
|
|
899
967
|
|
|
900
|
-
env = Env.new(StaticEnv.new(recv, Type.nil, false), locals, [], Utils::HashWrapper.new({}))
|
|
968
|
+
env = Env.new(StaticEnv.new(recv, Type.nil, false, true), locals, [], Utils::HashWrapper.new({}))
|
|
901
969
|
|
|
902
|
-
|
|
970
|
+
if !@pending_execution[iseq] || @pending_execution[iseq][0] == :block
|
|
971
|
+
@pending_execution[iseq] = [:method, [meth, ep, env]]
|
|
972
|
+
end
|
|
903
973
|
end
|
|
904
974
|
|
|
905
975
|
def pend_block_dummy_execution(blk, iseq, nep, nenv)
|
|
@@ -916,7 +986,7 @@ module TypeProf
|
|
|
916
986
|
alloc_site = AllocationSite.new(ep)
|
|
917
987
|
nenv, ty = localize_type(ty, env, ep, alloc_site)
|
|
918
988
|
case ty
|
|
919
|
-
when Type::
|
|
989
|
+
when Type::Local
|
|
920
990
|
@alloc_site_to_global_id[ty.id] = [recv, var] # need overwrite check??
|
|
921
991
|
end
|
|
922
992
|
yield ty, nenv
|
|
@@ -1082,31 +1152,7 @@ module TypeProf
|
|
|
1082
1152
|
|
|
1083
1153
|
when :definemethod
|
|
1084
1154
|
mid, iseq = operands
|
|
1085
|
-
|
|
1086
|
-
recv = env.static_env.recv_ty
|
|
1087
|
-
if cref.klass.is_a?(Type::Class)
|
|
1088
|
-
typed_mdef = check_typed_method(cref.klass, mid, ep.ctx.cref.singleton)
|
|
1089
|
-
recv = Type::Instance.new(recv) if recv.is_a?(Type::Class)
|
|
1090
|
-
if typed_mdef
|
|
1091
|
-
mdef = ISeqMethodDef.new(iseq, cref)
|
|
1092
|
-
typed_mdef.each do |typed_mdef|
|
|
1093
|
-
typed_mdef.do_match_iseq_mdef(mdef, recv, mid, env, ep, self)
|
|
1094
|
-
end
|
|
1095
|
-
else
|
|
1096
|
-
if ep.ctx.cref.singleton
|
|
1097
|
-
meth = add_singleton_iseq_method(cref.klass, mid, iseq, cref)
|
|
1098
|
-
else
|
|
1099
|
-
meth = add_iseq_method(cref.klass, mid, iseq, cref)
|
|
1100
|
-
if env.static_env.mod_func
|
|
1101
|
-
add_singleton_iseq_method(cref.klass, mid, iseq, cref)
|
|
1102
|
-
end
|
|
1103
|
-
end
|
|
1104
|
-
|
|
1105
|
-
pend_method_execution(iseq, meth, recv, mid, ep.ctx.cref)
|
|
1106
|
-
end
|
|
1107
|
-
else
|
|
1108
|
-
# XXX: what to do?
|
|
1109
|
-
end
|
|
1155
|
+
do_define_iseq_method(ep, env, mid, iseq, nil)
|
|
1110
1156
|
|
|
1111
1157
|
when :definesmethod
|
|
1112
1158
|
mid, iseq = operands
|
|
@@ -1114,8 +1160,8 @@ module TypeProf
|
|
|
1114
1160
|
cref = ep.ctx.cref
|
|
1115
1161
|
recv.each_child do |recv|
|
|
1116
1162
|
if recv.is_a?(Type::Class)
|
|
1117
|
-
meth = add_singleton_iseq_method(recv, mid, iseq, cref)
|
|
1118
|
-
pend_method_execution(iseq, meth, recv, mid, ep.ctx.cref)
|
|
1163
|
+
meth = add_singleton_iseq_method(recv, mid, iseq, cref, nil, env.static_env.pub_meth)
|
|
1164
|
+
pend_method_execution(iseq, meth, recv, mid, ep.ctx.cref, nil)
|
|
1119
1165
|
else
|
|
1120
1166
|
recv = Type.any # XXX: what to do?
|
|
1121
1167
|
end
|
|
@@ -1132,35 +1178,30 @@ module TypeProf
|
|
|
1132
1178
|
else
|
|
1133
1179
|
if existing_klass != Type.any
|
|
1134
1180
|
error(ep, "the class \"#{ id }\" is #{ existing_klass.screen_name(self) }")
|
|
1135
|
-
id = :"#{ id }(dummy)"
|
|
1136
1181
|
end
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
superclass = Type::Builtin[:obj]
|
|
1149
|
-
elsif superclass.is_a?(Type::Instance)
|
|
1150
|
-
warn(ep, "superclass is an instance; Object is used instead")
|
|
1151
|
-
superclass = Type::Builtin[:obj]
|
|
1152
|
-
else
|
|
1153
|
-
warn(ep, "superclass is not a class; Object is used instead")
|
|
1154
|
-
superclass = Type::Builtin[:obj]
|
|
1155
|
-
end
|
|
1156
|
-
else # module
|
|
1157
|
-
superclass = nil
|
|
1158
|
-
end
|
|
1159
|
-
if cbase == Type.any
|
|
1160
|
-
klass = Type.any
|
|
1182
|
+
if type == :class
|
|
1183
|
+
if superclass.is_a?(Type::Class)
|
|
1184
|
+
# okay
|
|
1185
|
+
elsif superclass == Type.any
|
|
1186
|
+
warn(ep, "superclass is any; Object is used instead")
|
|
1187
|
+
superclass = Type::Builtin[:obj]
|
|
1188
|
+
elsif superclass == Type.nil
|
|
1189
|
+
superclass = Type::Builtin[:obj]
|
|
1190
|
+
elsif superclass.is_a?(Type::Instance)
|
|
1191
|
+
warn(ep, "superclass is an instance; Object is used instead")
|
|
1192
|
+
superclass = Type::Builtin[:obj]
|
|
1161
1193
|
else
|
|
1162
|
-
|
|
1194
|
+
warn(ep, "superclass is not a class; Object is used instead")
|
|
1195
|
+
superclass = Type::Builtin[:obj]
|
|
1163
1196
|
end
|
|
1197
|
+
else # module
|
|
1198
|
+
superclass = nil
|
|
1199
|
+
end
|
|
1200
|
+
if cbase == Type.any
|
|
1201
|
+
klass = Type.any
|
|
1202
|
+
else
|
|
1203
|
+
klass = new_class(cbase, id, [], superclass, ep.ctx.iseq.absolute_path)
|
|
1204
|
+
add_superclass_type_args!(klass, superclass.type_params.map { Type.any }) if superclass
|
|
1164
1205
|
end
|
|
1165
1206
|
end
|
|
1166
1207
|
singleton = false
|
|
@@ -1182,7 +1223,7 @@ module TypeProf
|
|
|
1182
1223
|
nctx = Context.new(iseq, ncref, nil)
|
|
1183
1224
|
nep = ExecutionPoint.new(nctx, 0, nil)
|
|
1184
1225
|
locals = [Type.nil] * iseq.locals.size
|
|
1185
|
-
nenv = Env.new(StaticEnv.new(recv, blk, false), locals, [], Utils::HashWrapper.new({}))
|
|
1226
|
+
nenv = Env.new(StaticEnv.new(recv, blk, false, true), locals, [], Utils::HashWrapper.new({}))
|
|
1186
1227
|
merge_env(nep, nenv)
|
|
1187
1228
|
add_callsite!(nep.ctx, ep, env) do |ret_ty, ep, env|
|
|
1188
1229
|
nenv, ret_ty = localize_type(ret_ty, env, ep)
|
|
@@ -1248,30 +1289,30 @@ module TypeProf
|
|
|
1248
1289
|
end
|
|
1249
1290
|
when :invokesuper
|
|
1250
1291
|
env, recv, _, aargs = setup_actual_arguments(:method, operands, ep, env)
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1292
|
+
mid = ep.ctx.mid
|
|
1293
|
+
found = false
|
|
1294
|
+
recv.each_child_global do |recv|
|
|
1295
|
+
klass, singleton = recv.method_dispatch_info
|
|
1296
|
+
next unless klass
|
|
1297
|
+
get_all_super_methods(klass, singleton, ep.ctx.cref.klass, ep.ctx.mid) do |meths, klass|
|
|
1298
|
+
found = true
|
|
1299
|
+
meths.each do |meth|
|
|
1300
|
+
# XXX: this decomposition is really needed??
|
|
1301
|
+
# It calls `Object.new` with union receiver which causes an error, but
|
|
1302
|
+
# it may be a fault of builtin Object.new implementation.
|
|
1303
|
+
recv.each_child do |recv|
|
|
1304
|
+
meth.do_send(recv, mid, aargs, ep, env, self) do |ret_ty, ep, env|
|
|
1305
|
+
nenv, ret_ty, = localize_type(ret_ty, env, ep)
|
|
1306
|
+
nenv = nenv.push(ret_ty)
|
|
1307
|
+
merge_env(ep.next, nenv)
|
|
1308
|
+
end
|
|
1267
1309
|
end
|
|
1268
1310
|
end
|
|
1269
1311
|
end
|
|
1270
|
-
return
|
|
1271
|
-
else
|
|
1272
|
-
error(ep, "no superclass method: #{ env.static_env.recv_ty.screen_name(self) }##{ mid }")
|
|
1273
|
-
env = env.push(Type.any)
|
|
1274
1312
|
end
|
|
1313
|
+
return if found
|
|
1314
|
+
error(ep, "no superclass method: #{ env.static_env.recv_ty.screen_name(self) }##{ mid }")
|
|
1315
|
+
env = env.push(Type.any)
|
|
1275
1316
|
when :invokebuiltin
|
|
1276
1317
|
raise NotImplementedError
|
|
1277
1318
|
when :leave
|
|
@@ -1495,9 +1536,7 @@ module TypeProf
|
|
|
1495
1536
|
ret_ty.each_child do |ret_ty|
|
|
1496
1537
|
flow_env = env.local_update(-var_idx+2, ret_ty)
|
|
1497
1538
|
ret_ty = ret_ty.base_type if ret_ty.is_a?(Type::Symbol)
|
|
1498
|
-
ret_ty = ret_ty.base_type if ret_ty.is_a?(Type::
|
|
1499
|
-
ret_ty = ret_ty.base_type if ret_ty.is_a?(Type::LocalArray)
|
|
1500
|
-
ret_ty = ret_ty.base_type if ret_ty.is_a?(Type::LocalHash)
|
|
1539
|
+
ret_ty = ret_ty.base_type if ret_ty.is_a?(Type::Local)
|
|
1501
1540
|
if ret_ty.is_a?(Type::Instance)
|
|
1502
1541
|
if ret_ty.klass == pattern_ty # XXX: inheritance
|
|
1503
1542
|
merge_env(branchtype == :if ? ep_else : ep_then, flow_env)
|
|
@@ -1663,9 +1702,13 @@ module TypeProf
|
|
|
1663
1702
|
from_head = flag & 2 == 0
|
|
1664
1703
|
ary.each_child do |ary|
|
|
1665
1704
|
case ary
|
|
1666
|
-
when Type::
|
|
1667
|
-
|
|
1668
|
-
|
|
1705
|
+
when Type::Local
|
|
1706
|
+
if ary.kind == Type::Array
|
|
1707
|
+
elems = get_container_elem_types(env, ep, ary.id)
|
|
1708
|
+
elems ||= Type::Array::Elements.new([], Type.any) # XXX
|
|
1709
|
+
else
|
|
1710
|
+
elems = Type::Array::Elements.new([], Type.any) # XXX
|
|
1711
|
+
end
|
|
1669
1712
|
do_expand_array(ep, env, elems, num, splat, from_head)
|
|
1670
1713
|
when Type::Any
|
|
1671
1714
|
nnum = num
|
|
@@ -1685,9 +1728,9 @@ module TypeProf
|
|
|
1685
1728
|
return
|
|
1686
1729
|
when :concatarray
|
|
1687
1730
|
env, (ary1, ary2) = env.pop(2)
|
|
1688
|
-
if ary1.is_a?(Type::
|
|
1731
|
+
if ary1.is_a?(Type::Local) && ary1.kind == Type::Array
|
|
1689
1732
|
elems1 = get_container_elem_types(env, ep, ary1.id)
|
|
1690
|
-
if ary2.is_a?(Type::
|
|
1733
|
+
if ary2.is_a?(Type::Local) && ary2.kind == Type::Array
|
|
1691
1734
|
elems2 = get_container_elem_types(env, ep, ary2.id)
|
|
1692
1735
|
elems = Type::Array::Elements.new([], elems1.squash.union(elems2.squash))
|
|
1693
1736
|
env = update_container_elem_types(env, ep, ary1.id, ary1.base_type) { elems }
|
|
@@ -1909,7 +1952,7 @@ module TypeProf
|
|
|
1909
1952
|
nctx = Context.new(blk_iseq, ep.ctx.cref, ep.ctx.mid)
|
|
1910
1953
|
nep = ExecutionPoint.new(nctx, 0, ep)
|
|
1911
1954
|
nlocals = [Type.any] * blk_iseq.locals.size
|
|
1912
|
-
nsenv = StaticEnv.new(env.static_env.recv_ty, Type.any, env.static_env.mod_func)
|
|
1955
|
+
nsenv = StaticEnv.new(env.static_env.recv_ty, Type.any, env.static_env.mod_func, env.static_env.pub_meth)
|
|
1913
1956
|
nenv = Env.new(nsenv, nlocals, [], nil)
|
|
1914
1957
|
pend_block_dummy_execution(blk_ty, blk_iseq, nep, nenv)
|
|
1915
1958
|
merge_return_env(ep) {|tenv| tenv ? tenv.merge(env) : env }
|
|
@@ -1919,20 +1962,31 @@ module TypeProf
|
|
|
1919
1962
|
end
|
|
1920
1963
|
|
|
1921
1964
|
def do_send(recv, mid, aargs, ep, env, &ctn)
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1965
|
+
case recv
|
|
1966
|
+
when Type::Void
|
|
1967
|
+
error(ep, "void's method is called: #{ globalize_type(recv, env, ep).screen_name(self) }##{ mid }")
|
|
1968
|
+
ctn[Type.any, ep, env]
|
|
1969
|
+
when Type::Any
|
|
1970
|
+
ctn[Type.any, ep, env]
|
|
1927
1971
|
else
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1972
|
+
klass, singleton = recv.method_dispatch_info
|
|
1973
|
+
meths = get_method(klass, singleton, mid) if klass
|
|
1974
|
+
if meths
|
|
1975
|
+
meths.each do |meth|
|
|
1976
|
+
meth.do_send(recv, mid, aargs, ep, env, self, &ctn)
|
|
1977
|
+
end
|
|
1932
1978
|
else
|
|
1933
|
-
|
|
1979
|
+
meths = get_method(klass, singleton, :method_missing) if klass
|
|
1980
|
+
if meths
|
|
1981
|
+
aargs = aargs.for_method_missing(Type::Symbol.new(mid, Type::Instance.new(Type::Builtin[:sym])))
|
|
1982
|
+
meths.each do |meth|
|
|
1983
|
+
meth.do_send(recv, :method_missing, aargs, ep, env, self, &ctn)
|
|
1984
|
+
end
|
|
1985
|
+
else
|
|
1986
|
+
error(ep, "undefined method: #{ globalize_type(recv, env, ep).screen_name(self) }##{ mid }")
|
|
1987
|
+
ctn[Type.any, ep, env]
|
|
1988
|
+
end
|
|
1934
1989
|
end
|
|
1935
|
-
ctn[Type.any, ep, env]
|
|
1936
1990
|
end
|
|
1937
1991
|
end
|
|
1938
1992
|
|
|
@@ -1947,6 +2001,34 @@ module TypeProf
|
|
|
1947
2001
|
end
|
|
1948
2002
|
end
|
|
1949
2003
|
|
|
2004
|
+
def do_define_iseq_method(ep, env, mid, iseq, outer_ep)
|
|
2005
|
+
cref = ep.ctx.cref
|
|
2006
|
+
recv = env.static_env.recv_ty
|
|
2007
|
+
if cref.klass.is_a?(Type::Class)
|
|
2008
|
+
typed_mdef = check_typed_method(cref.klass, mid, ep.ctx.cref.singleton)
|
|
2009
|
+
recv = Type::Instance.new(recv) if recv.is_a?(Type::Class)
|
|
2010
|
+
if typed_mdef
|
|
2011
|
+
mdef = ISeqMethodDef.new(iseq, cref, outer_ep, env.static_env.pub_meth)
|
|
2012
|
+
typed_mdef.each do |typed_mdef|
|
|
2013
|
+
typed_mdef.do_match_iseq_mdef(mdef, recv, mid, env, ep, self)
|
|
2014
|
+
end
|
|
2015
|
+
else
|
|
2016
|
+
if ep.ctx.cref.singleton
|
|
2017
|
+
meth = add_singleton_iseq_method(cref.klass, mid, iseq, cref, outer_ep, true)
|
|
2018
|
+
else
|
|
2019
|
+
meth = add_iseq_method(cref.klass, mid, iseq, cref, outer_ep, env.static_env.pub_meth)
|
|
2020
|
+
if env.static_env.mod_func
|
|
2021
|
+
add_singleton_iseq_method(cref.klass, mid, iseq, cref, outer_ep, true)
|
|
2022
|
+
end
|
|
2023
|
+
end
|
|
2024
|
+
|
|
2025
|
+
pend_method_execution(iseq, meth, recv, mid, ep.ctx.cref, outer_ep)
|
|
2026
|
+
end
|
|
2027
|
+
else
|
|
2028
|
+
# XXX: what to do?
|
|
2029
|
+
end
|
|
2030
|
+
end
|
|
2031
|
+
|
|
1950
2032
|
def show_block_signature(blks)
|
|
1951
2033
|
bsig = nil
|
|
1952
2034
|
ret_ty = Type.bot
|