typeprof 0.5.3 → 0.8.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 +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
|