typeprof 0.9.2 → 0.10.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 +3 -2
- data/lib/typeprof/analyzer.rb +82 -59
- data/lib/typeprof/block.rb +34 -0
- data/lib/typeprof/builtin.rb +169 -64
- data/lib/typeprof/cli.rb +2 -0
- data/lib/typeprof/config.rb +13 -1
- data/lib/typeprof/export.rb +114 -69
- data/lib/typeprof/import.rb +50 -28
- data/lib/typeprof/iseq.rb +23 -4
- data/lib/typeprof/method.rb +29 -7
- data/lib/typeprof/type.rb +41 -13
- data/lib/typeprof/version.rb +1 -1
- data/smoke/alias.rb +4 -4
- data/smoke/alias2.rb +3 -1
- data/smoke/arguments.rb +2 -2
- data/smoke/arguments2.rb +5 -5
- data/smoke/array-each.rb +1 -1
- data/smoke/array-each3.rb +1 -1
- data/smoke/array-map.rb +1 -1
- data/smoke/array-map2.rb +1 -1
- data/smoke/array-map3.rb +3 -3
- data/smoke/array-mul.rb +2 -2
- data/smoke/array-plus1.rb +1 -1
- data/smoke/array-plus2.rb +1 -0
- data/smoke/array-range-aref.rb +11 -11
- data/smoke/array-replace.rb +1 -1
- data/smoke/array1.rb +5 -5
- data/smoke/array10.rb +1 -1
- data/smoke/array11.rb +1 -1
- data/smoke/array12.rb +1 -1
- data/smoke/array14.rb +1 -1
- data/smoke/array15.rb +1 -1
- data/smoke/array2.rb +2 -2
- data/smoke/array3.rb +1 -0
- data/smoke/array6.rb +2 -1
- data/smoke/array8.rb +1 -1
- data/smoke/array9.rb +1 -1
- data/smoke/attr-module.rb +1 -0
- data/smoke/attr-vis.rb +43 -0
- data/smoke/attr-vis.rbs +4 -0
- data/smoke/attr.rb +2 -2
- data/smoke/block-ambiguous.rb +4 -4
- data/smoke/block-args1-rest.rb +6 -5
- data/smoke/block-args1.rb +5 -5
- data/smoke/block-args2-rest.rb +6 -5
- data/smoke/block-args2.rb +5 -5
- data/smoke/block-args3-rest.rb +7 -6
- data/smoke/block-args3.rb +6 -6
- data/smoke/block-blockarg.rb +3 -3
- data/smoke/block-kwarg.rb +4 -4
- data/smoke/block1.rb +1 -1
- data/smoke/block10.rb +1 -1
- data/smoke/block11.rb +2 -2
- data/smoke/block2.rb +1 -1
- data/smoke/block3.rb +1 -1
- data/smoke/block5.rb +1 -0
- data/smoke/block_given.rb +37 -0
- data/smoke/class_method.rb +2 -2
- data/smoke/class_method2.rb +2 -2
- data/smoke/constant2.rb +3 -2
- data/smoke/context-sensitive1.rb +1 -1
- data/smoke/cvar.rb +3 -2
- data/smoke/define_method.rb +2 -2
- data/smoke/define_method3.rb +1 -0
- data/smoke/define_method4.rb +1 -1
- data/smoke/define_method6.rb +19 -0
- data/smoke/demo.rb +6 -6
- data/smoke/demo1.rb +1 -1
- data/smoke/demo11.rb +1 -1
- data/smoke/demo2.rb +1 -1
- data/smoke/demo3.rb +1 -1
- data/smoke/demo4.rb +3 -3
- data/smoke/demo5.rb +1 -1
- data/smoke/demo6.rb +2 -1
- data/smoke/demo7.rb +1 -1
- data/smoke/demo9.rb +1 -0
- data/smoke/dummy-execution1.rb +1 -1
- data/smoke/dummy-execution2.rb +1 -1
- data/smoke/dummy_element.rb +1 -1
- data/smoke/ensure1.rb +1 -1
- data/smoke/enum_for.rb +15 -0
- data/smoke/enum_for2.rb +17 -0
- data/smoke/fib.rb +2 -2
- data/smoke/flow1.rb +1 -1
- data/smoke/flow10.rb +17 -0
- data/smoke/flow2.rb +1 -1
- data/smoke/flow3.rb +1 -1
- data/smoke/flow5.rb +1 -1
- data/smoke/flow6.rb +1 -1
- data/smoke/flow7.rb +1 -1
- data/smoke/flow8.rb +1 -1
- data/smoke/flow9.rb +1 -1
- data/smoke/function.rb +1 -1
- data/smoke/gvar.rb +1 -1
- data/smoke/gvar2.rb +1 -1
- data/smoke/hash-fetch.rb +3 -3
- data/smoke/inheritance.rb +4 -4
- data/smoke/initialize.rb +3 -2
- data/smoke/instance_eval.rb +1 -1
- data/smoke/int_times.rb +1 -1
- data/smoke/integer.rb +1 -1
- data/smoke/ivar.rb +3 -2
- data/smoke/ivar2.rb +2 -2
- data/smoke/ivar3.rb +2 -1
- data/smoke/ivar4.rb +1 -0
- data/smoke/kernel-class.rb +1 -1
- data/smoke/keyword4.rb +1 -1
- data/smoke/kwrest.rb +1 -0
- data/smoke/kwsplat1.rb +2 -2
- data/smoke/kwsplat2.rb +1 -1
- data/smoke/manual-rbs.rb +1 -0
- data/smoke/manual-rbs3.rb +1 -0
- data/smoke/method_missing.rb +4 -3
- data/smoke/module3.rb +1 -1
- data/smoke/module4.rb +1 -0
- data/smoke/module5.rb +1 -1
- data/smoke/module_function1.rb +3 -2
- data/smoke/module_function2.rb +3 -2
- data/smoke/multiple-include.rb +1 -0
- data/smoke/next1.rb +1 -1
- data/smoke/object-send1.rb +3 -3
- data/smoke/optional1.rb +1 -1
- data/smoke/optional2.rb +1 -1
- data/smoke/optional3.rb +1 -1
- data/smoke/parameterizedd-self.rb +2 -1
- data/smoke/prepend1.rb +33 -0
- data/smoke/prepend2.rb +10 -0
- data/smoke/prepend2.rbs +9 -0
- data/smoke/primitive_method.rb +19 -0
- data/smoke/proc4.rb +1 -1
- data/smoke/public.rb +4 -0
- data/smoke/range.rb +1 -1
- data/smoke/rbs-attr.rb +2 -2
- data/smoke/rbs-proc2.rb +1 -1
- data/smoke/rbs-proc3.rb +1 -1
- data/smoke/rbs-tyvar4.rb +3 -2
- data/smoke/rbs-tyvar6.rb +3 -3
- data/smoke/redo1.rb +1 -1
- data/smoke/redo2.rb +1 -1
- data/smoke/rescue1.rb +1 -1
- data/smoke/rescue2.rb +1 -1
- data/smoke/rescue3.rb +1 -0
- data/smoke/rescue4.rb +1 -1
- data/smoke/respond_to.rb +1 -1
- data/smoke/rest1.rb +2 -2
- data/smoke/rest2.rb +1 -1
- data/smoke/rest3.rb +6 -6
- data/smoke/rest4.rb +2 -2
- data/smoke/rest5.rb +1 -1
- data/smoke/rest6.rb +1 -1
- data/smoke/retry1.rb +2 -2
- data/smoke/simple.rb +1 -1
- data/smoke/step.rb +3 -3
- data/smoke/struct-keyword_init.rb +5 -15
- data/smoke/struct5.rb +1 -1
- data/smoke/struct6.rb +1 -1
- data/smoke/super1.rb +4 -4
- data/smoke/super3.rb +3 -2
- data/smoke/super4.rb +7 -5
- data/smoke/super5.rb +6 -4
- data/smoke/symbol-proc-attr.rb +1 -1
- data/smoke/tap1.rb +2 -2
- data/smoke/toplevel.rb +1 -1
- data/smoke/type_var.rb +3 -3
- data/smoke/user-demo.rb +1 -1
- data/smoke/wrong-extend.rb +1 -0
- data/smoke/wrong-include.rb +1 -0
- data/smoke/wrong-include2.rb +1 -1
- metadata +14 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8d68099e4f5d60a45f949d6bfc3a47e8b7d3b7ba66a0794f25f5fe61628de1d1
|
4
|
+
data.tar.gz: 22792d1acb9b16a4150f1afbaf29d59987bf29772908b23075e6668df81a4309
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42faa4e3b5c64fd5976e66067bf13339c530785914caad77bc0a405939bc914e9adf78bfbd0aea57a829cb21aed3c6dfc09f8f57def85b09312facd82d33b5a9
|
7
|
+
data.tar.gz: bc6f115fbf1d5292286f04f09d745cfb0c13688a71fdae730d0cfdd903ad8f9f3f9019e532c37b4cf23fe41f39c9a1683f92f28af68716ddf7e625a0efca33f8
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
typeprof (0.
|
4
|
+
typeprof (0.10.0)
|
5
5
|
rbs (>= 0.20.1)
|
6
6
|
|
7
7
|
GEM
|
@@ -24,6 +24,7 @@ GEM
|
|
24
24
|
|
25
25
|
PLATFORMS
|
26
26
|
ruby
|
27
|
+
x86_64-linux
|
27
28
|
|
28
29
|
DEPENDENCIES
|
29
30
|
coverage-helpers
|
@@ -35,4 +36,4 @@ DEPENDENCIES
|
|
35
36
|
typeprof!
|
36
37
|
|
37
38
|
BUNDLED WITH
|
38
|
-
2.2.
|
39
|
+
2.2.1
|
data/lib/typeprof/analyzer.rb
CHANGED
@@ -117,30 +117,6 @@ module TypeProf
|
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
|
-
class TopStaticEnv
|
121
|
-
include Utils::StructuralEquality
|
122
|
-
|
123
|
-
def recv_ty
|
124
|
-
Type.bot
|
125
|
-
end
|
126
|
-
|
127
|
-
def blk_ty
|
128
|
-
Type.nil
|
129
|
-
end
|
130
|
-
|
131
|
-
def mod_func
|
132
|
-
false
|
133
|
-
end
|
134
|
-
|
135
|
-
def pub_meth
|
136
|
-
true
|
137
|
-
end
|
138
|
-
|
139
|
-
def merge(other)
|
140
|
-
raise unless other.is_a?(TopStaticEnv)
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
120
|
class Env
|
145
121
|
include Utils::StructuralEquality
|
146
122
|
|
@@ -246,6 +222,11 @@ module TypeProf
|
|
246
222
|
Env.new(senv, @locals, @stack, @type_params)
|
247
223
|
end
|
248
224
|
|
225
|
+
def replace_blk_ty(ty)
|
226
|
+
senv = StaticEnv.new(@static_env.recv_ty, ty, @static_env.mod_func, @static_env.pub_meth)
|
227
|
+
Env.new(senv, @locals, @stack, @type_params)
|
228
|
+
end
|
229
|
+
|
249
230
|
def inspect
|
250
231
|
"Env[#{ @static_env.inspect }, locals:#{ @locals.inspect }, stack:#{ @stack.inspect }, type_params:#{ (@type_params&.internal_hash).inspect }]"
|
251
232
|
end
|
@@ -319,7 +300,10 @@ module TypeProf
|
|
319
300
|
def initialize(kind, name, absolute_path)
|
320
301
|
raise unless name.is_a?(Array)
|
321
302
|
@kind = kind
|
322
|
-
@modules = {
|
303
|
+
@modules = {
|
304
|
+
:before => { true => [], false => [] }, # before = include/extend
|
305
|
+
:after => { true => [], false => [] }, # after = prepend
|
306
|
+
}
|
323
307
|
@name = name
|
324
308
|
@consts = {}
|
325
309
|
@methods = {}
|
@@ -332,13 +316,13 @@ module TypeProf
|
|
332
316
|
attr_reader :kind, :modules, :consts, :methods, :ivars, :cvars, :absolute_path
|
333
317
|
attr_accessor :name, :klass_obj
|
334
318
|
|
335
|
-
def
|
336
|
-
mod_, module_type_args, absolute_paths = @modules[singleton].find {|m,| m == mod }
|
319
|
+
def mix_module(kind, mod, type_args, singleton, absolute_path)
|
320
|
+
mod_, module_type_args, absolute_paths = @modules[kind][singleton].find {|m,| m == mod }
|
337
321
|
if mod_
|
338
|
-
raise "inconsistent include/extend type args in RBS?" if module_type_args != type_args && type_args != [] && type_args != nil
|
322
|
+
raise "inconsistent #{ kind == :after ? "include/extend" : "prepend" } type args in RBS?" if module_type_args != type_args && type_args != [] && type_args != nil
|
339
323
|
else
|
340
324
|
absolute_paths = Utils::MutableSet.new
|
341
|
-
@modules[singleton].unshift([mod, type_args, absolute_paths])
|
325
|
+
@modules[kind][singleton].unshift([mod, type_args, absolute_paths])
|
342
326
|
end
|
343
327
|
absolute_paths << absolute_path
|
344
328
|
end
|
@@ -355,10 +339,8 @@ module TypeProf
|
|
355
339
|
@consts[name] = [ty, absolute_path]
|
356
340
|
end
|
357
341
|
|
358
|
-
def
|
359
|
-
|
360
|
-
yield subst, direct if mthds&.include?(mthd)
|
361
|
-
@modules[singleton].each do |mod_def, type_args,|
|
342
|
+
def adjust_substitution_for_module(mods, mid, mthd, subst, &blk)
|
343
|
+
mods.each do |mod_def, type_args,|
|
362
344
|
if mod_def.klass_obj.type_params && type_args
|
363
345
|
subst2 = {}
|
364
346
|
mod_def.klass_obj.type_params.zip(type_args) do |(tyvar, *), tyarg|
|
@@ -370,13 +352,28 @@ module TypeProf
|
|
370
352
|
end
|
371
353
|
end
|
372
354
|
|
355
|
+
def adjust_substitution(singleton, mid, mthd, subst, direct, &blk)
|
356
|
+
adjust_substitution_for_module(@modules[:before][singleton], mid, mthd, subst, &blk)
|
357
|
+
|
358
|
+
mthds = @methods[[singleton, mid]]
|
359
|
+
yield subst, direct if mthds&.include?(mthd)
|
360
|
+
|
361
|
+
adjust_substitution_for_module(@modules[:after][singleton], mid, mthd, subst, &blk)
|
362
|
+
end
|
363
|
+
|
373
364
|
def search_method(singleton, mid, visited, &blk)
|
374
365
|
# Currently, circular inclusion of modules is allowed
|
375
366
|
return if visited[self]
|
376
367
|
visited[self] = true
|
368
|
+
|
369
|
+
@modules[:before][singleton].each do |mod_def,|
|
370
|
+
mod_def.search_method(false, mid, visited, &blk)
|
371
|
+
end
|
372
|
+
|
377
373
|
mthds = @methods[[singleton, mid]]
|
378
374
|
yield mthds, @klass_obj, singleton if mthds
|
379
|
-
|
375
|
+
|
376
|
+
@modules[:after][singleton].each do |mod_def,|
|
380
377
|
mod_def.search_method(false, mid, visited, &blk)
|
381
378
|
end
|
382
379
|
end
|
@@ -405,17 +402,17 @@ module TypeProf
|
|
405
402
|
end
|
406
403
|
end
|
407
404
|
|
408
|
-
def
|
409
|
-
return if
|
405
|
+
def mix_module(kind, mixing_mod, mixed_mod, type_args, singleton, caller_ep)
|
406
|
+
return if mixed_mod == Type.any
|
410
407
|
|
411
|
-
|
412
|
-
|
413
|
-
if
|
414
|
-
|
415
|
-
if
|
416
|
-
|
408
|
+
mixing_mod = @class_defs[mixing_mod.idx]
|
409
|
+
mixed_mod.each_child do |mixed_mod|
|
410
|
+
if mixed_mod.is_a?(Type::Class)
|
411
|
+
mixed_mod = @class_defs[mixed_mod.idx]
|
412
|
+
if mixed_mod && mixed_mod.kind == :module
|
413
|
+
mixing_mod.mix_module(kind, mixed_mod, type_args, singleton, caller_ep ? caller_ep.ctx.iseq.absolute_path : nil)
|
417
414
|
else
|
418
|
-
warn(caller_ep, "
|
415
|
+
warn(caller_ep, "attempted to #{ kind == :after ? "include/extend" : "prepend" } non-module; ignored")
|
419
416
|
end
|
420
417
|
end
|
421
418
|
end
|
@@ -602,12 +599,12 @@ module TypeProf
|
|
602
599
|
mdef
|
603
600
|
end
|
604
601
|
|
605
|
-
def add_attr_method(klass,
|
602
|
+
def add_attr_method(klass, mid, ivar, kind, pub_meth, ep)
|
606
603
|
if kind == :reader || kind == :accessor
|
607
|
-
add_method(klass, mid, false, AttrMethodDef.new(ivar, :reader,
|
604
|
+
add_method(klass, mid, false, AttrMethodDef.new(ivar, :reader, pub_meth, ep))
|
608
605
|
end
|
609
606
|
if kind == :writer || kind == :accessor
|
610
|
-
add_method(klass, :"#{ mid }=", false, AttrMethodDef.new(ivar, :writer,
|
607
|
+
add_method(klass, :"#{ mid }=", false, AttrMethodDef.new(ivar, :writer, pub_meth, ep))
|
611
608
|
end
|
612
609
|
end
|
613
610
|
|
@@ -619,22 +616,22 @@ module TypeProf
|
|
619
616
|
add_method(klass, mid, true, ISeqMethodDef.new(iseq, cref, outer_ep, pub_meth))
|
620
617
|
end
|
621
618
|
|
622
|
-
def set_custom_method(klass, mid, impl)
|
623
|
-
set_method(klass, mid, false, CustomMethodDef.new(impl))
|
619
|
+
def set_custom_method(klass, mid, impl, pub_meth = true)
|
620
|
+
set_method(klass, mid, false, CustomMethodDef.new(impl, pub_meth))
|
624
621
|
end
|
625
622
|
|
626
|
-
def set_singleton_custom_method(klass, mid, impl)
|
627
|
-
set_method(klass, mid, true, CustomMethodDef.new(impl))
|
623
|
+
def set_singleton_custom_method(klass, mid, impl, pub_meth = true)
|
624
|
+
set_method(klass, mid, true, CustomMethodDef.new(impl, pub_meth))
|
628
625
|
end
|
629
626
|
|
630
|
-
def alias_method(klass, singleton,
|
627
|
+
def alias_method(klass, singleton, alias_mid, orig_mid, ep)
|
631
628
|
if klass == Type.any
|
632
629
|
self
|
633
630
|
else
|
634
|
-
mdefs = get_method(klass, singleton,
|
631
|
+
mdefs = get_method(klass, singleton, orig_mid)
|
635
632
|
if mdefs
|
636
633
|
mdefs.each do |mdef|
|
637
|
-
@class_defs[klass.idx].add_method(
|
634
|
+
@class_defs[klass.idx].add_method(alias_mid, singleton, AliasMethodDef.new(orig_mid, mdef, ep))
|
638
635
|
end
|
639
636
|
end
|
640
637
|
end
|
@@ -723,7 +720,7 @@ module TypeProf
|
|
723
720
|
if ep
|
724
721
|
if entry.rbs_declared
|
725
722
|
unless Type.match?(ty, entry.type)
|
726
|
-
scratch.warn(ep, "inconsistent assignment to RBS-declared
|
723
|
+
scratch.warn(ep, "inconsistent assignment to RBS-declared variable")
|
727
724
|
return
|
728
725
|
end
|
729
726
|
end
|
@@ -1076,7 +1073,7 @@ module TypeProf
|
|
1076
1073
|
lead_tys = env.locals[0, lead_num].map {|ty| globalize_type(ty, env, ep) }
|
1077
1074
|
opt_tys = opt.size > 1 ? env.locals[lead_num, opt.size - 1].map {|ty| globalize_type(ty, env, ep) } : []
|
1078
1075
|
if rest_start # XXX:squash
|
1079
|
-
ty = globalize_type(env.locals[
|
1076
|
+
ty = globalize_type(env.locals[rest_start], env, ep)
|
1080
1077
|
rest_ty = Type.bot
|
1081
1078
|
ty.each_child_global do |ty|
|
1082
1079
|
if ty.is_a?(Type::Array)
|
@@ -1111,6 +1108,7 @@ module TypeProf
|
|
1111
1108
|
end
|
1112
1109
|
end
|
1113
1110
|
kw_rest_ty = globalize_type(env.locals[kw_rest], env, ep) if kw_rest
|
1111
|
+
kw_rest_ty = nil if kw_rest_ty == Type.nil
|
1114
1112
|
if block_start
|
1115
1113
|
blk_ty = globalize_type(env.locals[block_start], env, ep)
|
1116
1114
|
elsif iseq.type == :method
|
@@ -1290,7 +1288,7 @@ module TypeProf
|
|
1290
1288
|
end
|
1291
1289
|
end
|
1292
1290
|
return
|
1293
|
-
when :
|
1291
|
+
when :getlocal_send_branch
|
1294
1292
|
getlocal_operands, send_operands, branch_operands = operands
|
1295
1293
|
env, recvs, mid, aargs = setup_actual_arguments(:method, send_operands, ep, env)
|
1296
1294
|
recvs = Type.any if recvs == Type.bot
|
@@ -1318,6 +1316,31 @@ module TypeProf
|
|
1318
1316
|
end
|
1319
1317
|
end
|
1320
1318
|
return
|
1319
|
+
when :send_branch
|
1320
|
+
send_operands, branch_operands = operands
|
1321
|
+
env, recvs, mid, aargs = setup_actual_arguments(:method, send_operands, ep, env)
|
1322
|
+
recvs = Type.any if recvs == Type.bot
|
1323
|
+
recvs.each_child do |recv|
|
1324
|
+
do_send(recv, mid, aargs, ep, env) do |ret_ty, ep, env|
|
1325
|
+
env, ret_ty, = localize_type(ret_ty, env, ep)
|
1326
|
+
|
1327
|
+
branchtype, target, = branch_operands
|
1328
|
+
# branchtype: :if or :unless or :nil
|
1329
|
+
ep_then = ep.next
|
1330
|
+
ep_else = ep.jump(target)
|
1331
|
+
|
1332
|
+
case ret_ty
|
1333
|
+
when Type::Instance.new(Type::Builtin[:true])
|
1334
|
+
merge_env(branchtype == :if ? ep_else : ep_then, env)
|
1335
|
+
when Type::Instance.new(Type::Builtin[:false])
|
1336
|
+
merge_env(branchtype == :if ? ep_then : ep_else, env)
|
1337
|
+
else
|
1338
|
+
merge_env(ep_then, env)
|
1339
|
+
merge_env(ep_else, env)
|
1340
|
+
end
|
1341
|
+
end
|
1342
|
+
end
|
1343
|
+
return
|
1321
1344
|
when :invokeblock
|
1322
1345
|
env, recvs, mid, aargs = setup_actual_arguments(:block, operands, ep, env)
|
1323
1346
|
blk = env.static_env.blk_ty
|
@@ -2130,7 +2153,7 @@ module TypeProf
|
|
2130
2153
|
|
2131
2154
|
bsig ||= BlockSignature.new([], [], nil, Type.nil)
|
2132
2155
|
|
2133
|
-
bsig = bsig.screen_name(self)
|
2156
|
+
bsig = bsig.screen_name(nil, self)
|
2134
2157
|
ret_ty = ret_ty.screen_name(self)
|
2135
2158
|
ret_ty = (ret_ty.include?("|") ? "(#{ ret_ty })" : ret_ty) # XXX?
|
2136
2159
|
|
@@ -2157,7 +2180,7 @@ module TypeProf
|
|
2157
2180
|
end
|
2158
2181
|
end
|
2159
2182
|
|
2160
|
-
farg_tys = farg_tys ? farg_tys.screen_name(self) : "(unknown)"
|
2183
|
+
farg_tys = farg_tys ? farg_tys.screen_name(nil, self) : "(unknown)"
|
2161
2184
|
ret_ty = ret_ty.screen_name(self)
|
2162
2185
|
ret_ty = (ret_ty.include?("|") ? "(#{ ret_ty })" : ret_ty) # XXX?
|
2163
2186
|
|
@@ -2169,7 +2192,7 @@ module TypeProf
|
|
2169
2192
|
farg_tys = @method_signatures[ctx]
|
2170
2193
|
ret_ty = @return_values[ctx] || Type.bot
|
2171
2194
|
|
2172
|
-
farg_tys = farg_tys.screen_name(self)
|
2195
|
+
farg_tys = farg_tys.screen_name(ctx.iseq, self)
|
2173
2196
|
ret_ty = ret_ty.screen_name(self)
|
2174
2197
|
ret_ty = (ret_ty.include?("|") ? "(#{ ret_ty })" : ret_ty) # XXX?
|
2175
2198
|
"#{ (farg_tys.empty? ? "" : "#{ farg_tys } ") }-> #{ ret_ty }"
|
data/lib/typeprof/block.rb
CHANGED
@@ -137,4 +137,38 @@ module TypeProf
|
|
137
137
|
end
|
138
138
|
end
|
139
139
|
end
|
140
|
+
|
141
|
+
class CustomBlock < Block
|
142
|
+
def initialize(caller_ep, mid, &blk)
|
143
|
+
@caller_ep = caller_ep
|
144
|
+
@mid = mid
|
145
|
+
@blk = blk
|
146
|
+
end
|
147
|
+
|
148
|
+
def inspect
|
149
|
+
"#<CustomBlock>"
|
150
|
+
end
|
151
|
+
|
152
|
+
def consistent?(other)
|
153
|
+
true # XXX
|
154
|
+
end
|
155
|
+
|
156
|
+
def substitute(_subst, _depth)
|
157
|
+
self
|
158
|
+
end
|
159
|
+
|
160
|
+
def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, &ctn)
|
161
|
+
aargs = scratch.globalize_type(aargs, caller_env, caller_ep)
|
162
|
+
|
163
|
+
dummy_ctx = TypedContext.new(@caller_ep, @mid)
|
164
|
+
|
165
|
+
scratch.add_block_signature!(self, aargs.to_block_signature)
|
166
|
+
scratch.add_block_to_ctx!(self, dummy_ctx)
|
167
|
+
|
168
|
+
@blk.call(aargs, caller_ep, caller_env, scratch, replace_recv_ty: replace_recv_ty) do |ret_ty, ep, env|
|
169
|
+
scratch.add_return_value!(dummy_ctx, ret_ty)
|
170
|
+
ctn[ret_ty, ep, env]
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
140
174
|
end
|
data/lib/typeprof/builtin.rb
CHANGED
@@ -19,7 +19,7 @@ module TypeProf
|
|
19
19
|
klass, new_mid, old_mid = aargs.lead_tys
|
20
20
|
new_sym = get_sym("alias", new_mid, ep, scratch) or return
|
21
21
|
old_sym = get_sym("alias", old_mid, ep, scratch) or return
|
22
|
-
scratch.alias_method(klass, ep.ctx.cref.singleton, new_sym, old_sym)
|
22
|
+
scratch.alias_method(klass, ep.ctx.cref.singleton, new_sym, old_sym, ep)
|
23
23
|
ctn[Type.nil, ep, env]
|
24
24
|
end
|
25
25
|
|
@@ -163,6 +163,66 @@ module TypeProf
|
|
163
163
|
end
|
164
164
|
end
|
165
165
|
|
166
|
+
def object_enum_for(recv, mid, aargs, ep, env, scratch, &ctn)
|
167
|
+
if aargs.lead_tys.size >= 1
|
168
|
+
mid_ty, = aargs.lead_tys
|
169
|
+
naargs = ActualArguments.new(aargs.lead_tys[1..], aargs.rest_ty, aargs.kw_tys, aargs.blk_ty)
|
170
|
+
elsif aargs.rest_ty
|
171
|
+
mid_ty = aargs.rest_ty
|
172
|
+
naargs = aargs
|
173
|
+
else
|
174
|
+
mid_ty = Type::Symbol.new(:each, Type::Instance.new(Type::Builtin[:sym]))
|
175
|
+
naargs = aargs
|
176
|
+
end
|
177
|
+
|
178
|
+
elem_ty = Type.bot
|
179
|
+
enum_for_blk = CustomBlock.new(ep, mid) do |aargs, caller_ep, caller_env, scratch, replace_recv_ty:, &blk_ctn|
|
180
|
+
if aargs.lead_tys.size >= 1
|
181
|
+
elem_ty = elem_ty.union(aargs.lead_tys[0])
|
182
|
+
else
|
183
|
+
elem_ty = elem_ty.union(Type.any)
|
184
|
+
end
|
185
|
+
ctn[Type::Cell.new(Type::Cell::Elements.new([elem_ty, Type.any]), Type::Instance.new(Type::Builtin[:enumerator])), ep, env]
|
186
|
+
blk_ctn[Type.any, caller_ep, caller_env]
|
187
|
+
end
|
188
|
+
enum_for_blk_ty = Type::Proc.new(enum_for_blk, Type::Instance.new(Type::Builtin[:proc]))
|
189
|
+
|
190
|
+
naargs = ActualArguments.new(naargs.lead_tys, naargs.rest_ty, naargs.kw_tys, enum_for_blk_ty)
|
191
|
+
mid_ty.each_child do |mid|
|
192
|
+
if mid.is_a?(Type::Symbol)
|
193
|
+
mid = mid.sym
|
194
|
+
scratch.do_send(recv, mid, naargs, ep, env) do |_ret_ty, _ep|
|
195
|
+
ctn[Type::Cell.new(Type::Cell::Elements.new([elem_ty, Type.any]), Type::Instance.new(Type::Builtin[:enumerator])), ep, env]
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def object_privitive_method(recv, mid, aargs, ep, env, scratch, &ctn)
|
202
|
+
ctn[Type::Symbol.new(ep.ctx.mid, Type::Instance.new(Type::Builtin[:sym])), ep, env]
|
203
|
+
end
|
204
|
+
|
205
|
+
def object_block_given?(recv, mid, aargs, ep, env, scratch, &ctn)
|
206
|
+
procs = Type.bot
|
207
|
+
no_proc = false
|
208
|
+
env.static_env.blk_ty.each_child do |blk_ty|
|
209
|
+
case blk_ty
|
210
|
+
when Type::Proc
|
211
|
+
procs = procs.union(blk_ty)
|
212
|
+
when Type.nil
|
213
|
+
no_proc = true
|
214
|
+
else
|
215
|
+
ctn[Type.bool, ep, env]
|
216
|
+
end
|
217
|
+
end
|
218
|
+
if procs != Type.bot
|
219
|
+
ctn[Type::Instance.new(Type::Builtin[:true]), ep, env.replace_blk_ty(procs)]
|
220
|
+
end
|
221
|
+
if no_proc
|
222
|
+
ctn[Type::Instance.new(Type::Builtin[:false]), ep, env.replace_blk_ty(Type.nil)]
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
166
226
|
def module_include(recv, mid, aargs, ep, env, scratch, &ctn)
|
167
227
|
if aargs.lead_tys.size != 1
|
168
228
|
scratch.warn(ep, "Module#include without an argument is ignored")
|
@@ -178,7 +238,7 @@ module TypeProf
|
|
178
238
|
arg = aargs.lead_tys[0]
|
179
239
|
arg.each_child do |arg|
|
180
240
|
if arg.is_a?(Type::Class)
|
181
|
-
scratch.
|
241
|
+
scratch.mix_module(:after, recv, arg, nil, ep.ctx.cref.singleton, ep)
|
182
242
|
end
|
183
243
|
end
|
184
244
|
ctn[recv, ep, env]
|
@@ -199,7 +259,29 @@ module TypeProf
|
|
199
259
|
arg = aargs.lead_tys[0]
|
200
260
|
arg.each_child do |arg|
|
201
261
|
if arg.is_a?(Type::Class)
|
202
|
-
|
262
|
+
# if ep.ctx.cref.singleton is true, the meta-meta level is ignored. Should we warn?
|
263
|
+
scratch.mix_module(:after, recv, arg, nil, true, ep)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
ctn[recv, ep, env]
|
267
|
+
end
|
268
|
+
|
269
|
+
def module_prepend(recv, mid, aargs, ep, env, scratch, &ctn)
|
270
|
+
if aargs.lead_tys.size != 1
|
271
|
+
scratch.warn(ep, "Module#prepend without an argument is ignored")
|
272
|
+
ctn[Type.any, ep, env]
|
273
|
+
return
|
274
|
+
end
|
275
|
+
|
276
|
+
unless recv.is_a?(Type::Class)
|
277
|
+
# XXX: warn?
|
278
|
+
return ctn[Type.any, ep, env]
|
279
|
+
end
|
280
|
+
|
281
|
+
arg = aargs.lead_tys[0]
|
282
|
+
arg.each_child do |arg|
|
283
|
+
if arg.is_a?(Type::Class)
|
284
|
+
scratch.mix_module(:before, recv, arg, nil, ep.ctx.cref.singleton, ep)
|
203
285
|
end
|
204
286
|
end
|
205
287
|
ctn[recv, ep, env]
|
@@ -268,23 +350,25 @@ module TypeProf
|
|
268
350
|
end
|
269
351
|
|
270
352
|
mid, = aargs.lead_tys
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
353
|
+
mid.each_child do |mid|
|
354
|
+
if mid.is_a?(Type::Symbol)
|
355
|
+
mid = mid.sym
|
356
|
+
aargs.blk_ty.each_child do |blk_ty|
|
357
|
+
if blk_ty.is_a?(Type::Proc)
|
358
|
+
blk = blk_ty.block_body
|
359
|
+
case blk
|
360
|
+
when ISeqBlock
|
361
|
+
scratch.do_define_iseq_method(ep, env, mid, blk.iseq, blk.outer_ep)
|
362
|
+
else
|
363
|
+
# XXX: what to do?
|
364
|
+
end
|
279
365
|
else
|
280
366
|
# XXX: what to do?
|
281
367
|
end
|
282
|
-
else
|
283
|
-
# XXX: what to do?
|
284
368
|
end
|
369
|
+
else
|
370
|
+
# XXX: what to do?
|
285
371
|
end
|
286
|
-
else
|
287
|
-
# XXX: what to do?
|
288
372
|
end
|
289
373
|
ctn[Type.any, ep, env]
|
290
374
|
end
|
@@ -293,7 +377,7 @@ module TypeProf
|
|
293
377
|
aargs.lead_tys.each do |aarg|
|
294
378
|
sym = get_sym("attr_accessor", aarg, ep, scratch) or next
|
295
379
|
cref = ep.ctx.cref
|
296
|
-
scratch.add_attr_method(cref.klass,
|
380
|
+
scratch.add_attr_method(cref.klass, sym, :"@#{ sym }", :accessor, env.static_env.pub_meth, ep)
|
297
381
|
end
|
298
382
|
ctn[Type.nil, ep, env]
|
299
383
|
end
|
@@ -302,7 +386,7 @@ module TypeProf
|
|
302
386
|
aargs.lead_tys.each do |aarg|
|
303
387
|
sym = get_sym("attr_reader", aarg, ep, scratch) or next
|
304
388
|
cref = ep.ctx.cref
|
305
|
-
scratch.add_attr_method(cref.klass,
|
389
|
+
scratch.add_attr_method(cref.klass, sym, :"@#{ sym }", :reader, env.static_env.pub_meth, ep)
|
306
390
|
end
|
307
391
|
ctn[Type.nil, ep, env]
|
308
392
|
end
|
@@ -311,7 +395,7 @@ module TypeProf
|
|
311
395
|
aargs.lead_tys.each do |aarg|
|
312
396
|
sym = get_sym("attr_writer", aarg, ep, scratch) or next
|
313
397
|
cref = ep.ctx.cref
|
314
|
-
scratch.add_attr_method(cref.klass,
|
398
|
+
scratch.add_attr_method(cref.klass, sym, :"@#{ sym }", :writer, env.static_env.pub_meth, ep)
|
315
399
|
end
|
316
400
|
ctn[Type.nil, ep, env]
|
317
401
|
end
|
@@ -444,43 +528,57 @@ module TypeProf
|
|
444
528
|
ctn[Type.any, ep, env]
|
445
529
|
return
|
446
530
|
end
|
447
|
-
scratch.add_ivar_read!(Type::Instance.new(struct_klass), :
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
531
|
+
scratch.add_ivar_read!(Type::Instance.new(struct_klass), :_keyword_init, ep) do |keyword_init, ep|
|
532
|
+
scratch.add_ivar_read!(Type::Instance.new(struct_klass), :_members, ep) do |member_ary_ty, ep|
|
533
|
+
next if member_ary_ty == Type.nil
|
534
|
+
if keyword_init == Type::Instance.new(Type::Builtin[:true])
|
535
|
+
# TODO: support kw_rest_ty
|
536
|
+
aargs.kw_tys.each do |key, val_ty|
|
537
|
+
found = false
|
538
|
+
member_ary_ty.elems.lead_tys.each do |sym|
|
539
|
+
if sym.sym == key
|
540
|
+
found = true
|
541
|
+
scratch.set_instance_variable(recv, sym.sym, val_ty, ep, env)
|
542
|
+
end
|
543
|
+
end
|
544
|
+
unless found
|
545
|
+
# TODO: what to do when not found?
|
546
|
+
end
|
547
|
+
end
|
548
|
+
else
|
549
|
+
member_ary_ty.elems.lead_tys.zip(aargs.lead_tys) do |sym, ty|
|
550
|
+
ty ||= Type.nil
|
551
|
+
scratch.set_instance_variable(recv, sym.sym, ty, ep, env)
|
552
|
+
end
|
553
|
+
end
|
452
554
|
end
|
453
555
|
end
|
454
556
|
ctn[recv, ep, env]
|
455
557
|
end
|
456
558
|
|
457
|
-
def
|
559
|
+
def struct_s_new(recv, mid, aargs, ep, env, scratch, &ctn)
|
458
560
|
# TODO: keyword_init
|
459
561
|
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
ctn[recv, ep, env]
|
562
|
+
keyword_init = false
|
563
|
+
if aargs.kw_tys && aargs.kw_tys[:keyword_init] # XXX: more canonical way to extract keyword...
|
564
|
+
if aargs.kw_tys[:keyword_init] == Type::Instance.new(Type::Builtin[:true])
|
565
|
+
keyword_init = true
|
465
566
|
end
|
466
567
|
end
|
467
|
-
end
|
468
|
-
|
469
|
-
def struct_s_new(recv, mid, aargs, ep, env, scratch, &ctn)
|
470
|
-
# TODO: keyword_init
|
471
568
|
|
472
569
|
fields = aargs.lead_tys.map {|ty| get_sym("Struct.new", ty, ep, scratch) }.compact
|
473
570
|
struct_klass = scratch.new_struct(ep)
|
474
571
|
|
475
|
-
scratch.set_singleton_custom_method(struct_klass, :new, Builtin.method(:
|
476
|
-
scratch.set_singleton_custom_method(struct_klass, :[], Builtin.method(:
|
572
|
+
scratch.set_singleton_custom_method(struct_klass, :new, Builtin.method(:object_s_new))
|
573
|
+
scratch.set_singleton_custom_method(struct_klass, :[], Builtin.method(:object_s_new))
|
477
574
|
fields.each do |field|
|
478
|
-
scratch.add_attr_method(struct_klass,
|
575
|
+
scratch.add_attr_method(struct_klass, field, field, :accessor, true, ep)
|
479
576
|
end
|
480
577
|
fields = fields.map {|field| Type::Symbol.new(field, Type::Instance.new(Type::Builtin[:sym])) }
|
481
578
|
base_ty = Type::Instance.new(Type::Builtin[:ary])
|
482
579
|
fields = Type::Array.new(Type::Array::Elements.new(fields), base_ty)
|
483
580
|
scratch.add_ivar_write!(Type::Instance.new(struct_klass), :_members, fields, ep)
|
581
|
+
scratch.add_ivar_write!(Type::Instance.new(struct_klass), :_keyword_init, Type::Instance.new(Type::Builtin[:true]), ep) if keyword_init
|
484
582
|
#set_singleton_custom_method(struct_klass, :members, Builtin.method(:...))
|
485
583
|
|
486
584
|
ctn[struct_klass, ep, env]
|
@@ -654,25 +752,26 @@ module TypeProf
|
|
654
752
|
|
655
753
|
Import.import_builtin(scratch)
|
656
754
|
|
657
|
-
Type::Builtin[:vmcore]
|
658
|
-
Type::Builtin[:int]
|
659
|
-
Type::Builtin[:float]
|
660
|
-
Type::Builtin[:rational]
|
661
|
-
Type::Builtin[:complex]
|
662
|
-
Type::Builtin[:sym]
|
663
|
-
Type::Builtin[:str]
|
664
|
-
Type::Builtin[:struct]
|
665
|
-
Type::Builtin[:ary]
|
666
|
-
Type::Builtin[:hash]
|
667
|
-
Type::Builtin[:io]
|
668
|
-
Type::Builtin[:proc]
|
669
|
-
Type::Builtin[:range]
|
670
|
-
Type::Builtin[:regexp]
|
671
|
-
Type::Builtin[:matchdata]
|
672
|
-
Type::Builtin[:class]
|
673
|
-
Type::Builtin[:module]
|
674
|
-
Type::Builtin[:exc]
|
675
|
-
Type::Builtin[:encoding]
|
755
|
+
Type::Builtin[:vmcore] = scratch.new_class(klass_obj, :VMCore, [], klass_obj, nil)
|
756
|
+
Type::Builtin[:int] = scratch.get_constant(klass_obj, :Integer)
|
757
|
+
Type::Builtin[:float] = scratch.get_constant(klass_obj, :Float)
|
758
|
+
Type::Builtin[:rational] = scratch.get_constant(klass_obj, :Rational)
|
759
|
+
Type::Builtin[:complex] = scratch.get_constant(klass_obj, :Complex)
|
760
|
+
Type::Builtin[:sym] = scratch.get_constant(klass_obj, :Symbol)
|
761
|
+
Type::Builtin[:str] = scratch.get_constant(klass_obj, :String)
|
762
|
+
Type::Builtin[:struct] = scratch.get_constant(klass_obj, :Struct)
|
763
|
+
Type::Builtin[:ary] = scratch.get_constant(klass_obj, :Array)
|
764
|
+
Type::Builtin[:hash] = scratch.get_constant(klass_obj, :Hash)
|
765
|
+
Type::Builtin[:io] = scratch.get_constant(klass_obj, :IO)
|
766
|
+
Type::Builtin[:proc] = scratch.get_constant(klass_obj, :Proc)
|
767
|
+
Type::Builtin[:range] = scratch.get_constant(klass_obj, :Range)
|
768
|
+
Type::Builtin[:regexp] = scratch.get_constant(klass_obj, :Regexp)
|
769
|
+
Type::Builtin[:matchdata] = scratch.get_constant(klass_obj, :MatchData)
|
770
|
+
Type::Builtin[:class] = scratch.get_constant(klass_obj, :Class)
|
771
|
+
Type::Builtin[:module] = scratch.get_constant(klass_obj, :Module)
|
772
|
+
Type::Builtin[:exc] = scratch.get_constant(klass_obj, :Exception)
|
773
|
+
Type::Builtin[:encoding] = scratch.get_constant(klass_obj, :Encoding)
|
774
|
+
Type::Builtin[:enumerator] = scratch.get_constant(klass_obj, :Enumerator)
|
676
775
|
|
677
776
|
klass_vmcore = Type::Builtin[:vmcore]
|
678
777
|
klass_ary = Type::Builtin[:ary]
|
@@ -687,19 +786,25 @@ module TypeProf
|
|
687
786
|
scratch.set_custom_method(klass_vmcore, :"core#raise", Builtin.method(:vmcore_raise))
|
688
787
|
scratch.set_custom_method(klass_vmcore, :lambda, Builtin.method(:lambda))
|
689
788
|
scratch.set_singleton_custom_method(klass_obj, :"new", Builtin.method(:object_s_new))
|
690
|
-
scratch.set_custom_method(klass_obj, :p, Builtin.method(:kernel_p))
|
789
|
+
scratch.set_custom_method(klass_obj, :p, Builtin.method(:kernel_p), false)
|
691
790
|
scratch.set_custom_method(klass_obj, :is_a?, Builtin.method(:object_is_a?))
|
692
791
|
scratch.set_custom_method(klass_obj, :respond_to?, Builtin.method(:object_respond_to?))
|
693
792
|
scratch.set_custom_method(klass_obj, :class, Builtin.method(:object_class))
|
694
793
|
scratch.set_custom_method(klass_obj, :send, Builtin.method(:object_send))
|
695
794
|
scratch.set_custom_method(klass_obj, :instance_eval, Builtin.method(:object_instance_eval))
|
696
|
-
scratch.set_custom_method(klass_obj, :proc, Builtin.method(:lambda))
|
795
|
+
scratch.set_custom_method(klass_obj, :proc, Builtin.method(:lambda), false)
|
796
|
+
scratch.set_custom_method(klass_obj, :__method__, Builtin.method(:object_privitive_method), false)
|
797
|
+
scratch.set_custom_method(klass_obj, :block_given?, Builtin.method(:object_block_given?), false)
|
798
|
+
|
799
|
+
scratch.set_custom_method(klass_obj, :enum_for, Builtin.method(:object_enum_for))
|
800
|
+
scratch.set_custom_method(klass_obj, :to_enum, Builtin.method(:object_enum_for))
|
697
801
|
|
698
802
|
scratch.set_custom_method(klass_module, :include, Builtin.method(:module_include))
|
699
803
|
scratch.set_custom_method(klass_module, :extend, Builtin.method(:module_extend))
|
700
|
-
scratch.set_custom_method(klass_module, :
|
701
|
-
scratch.set_custom_method(klass_module, :
|
702
|
-
scratch.set_custom_method(klass_module, :
|
804
|
+
scratch.set_custom_method(klass_module, :prepend, Builtin.method(:module_prepend))
|
805
|
+
scratch.set_custom_method(klass_module, :module_function, Builtin.method(:module_module_function), false)
|
806
|
+
scratch.set_custom_method(klass_module, :public, Builtin.method(:module_public), false)
|
807
|
+
scratch.set_custom_method(klass_module, :private, Builtin.method(:module_private), false)
|
703
808
|
scratch.set_custom_method(klass_module, :define_method, Builtin.method(:module_define_method))
|
704
809
|
scratch.set_custom_method(klass_module, :"attr_accessor", Builtin.method(:module_attr_accessor))
|
705
810
|
scratch.set_custom_method(klass_module, :"attr_reader", Builtin.method(:module_attr_reader))
|
@@ -718,10 +823,10 @@ module TypeProf
|
|
718
823
|
scratch.set_custom_method(klass_struct, :initialize, Builtin.method(:struct_initialize))
|
719
824
|
scratch.set_singleton_custom_method(klass_struct, :new, Builtin.method(:struct_s_new))
|
720
825
|
|
721
|
-
scratch.set_custom_method(klass_obj, :require, Builtin.method(:kernel_require))
|
722
|
-
scratch.set_custom_method(klass_obj, :require_relative, Builtin.method(:kernel_require_relative))
|
723
|
-
scratch.set_custom_method(klass_obj, :Array, Builtin.method(:kernel_Array))
|
724
|
-
scratch.set_custom_method(klass_obj, :autoload, Builtin.method(:kernel_autoload))
|
826
|
+
scratch.set_custom_method(klass_obj, :require, Builtin.method(:kernel_require), false)
|
827
|
+
scratch.set_custom_method(klass_obj, :require_relative, Builtin.method(:kernel_require_relative), false)
|
828
|
+
scratch.set_custom_method(klass_obj, :Array, Builtin.method(:kernel_Array), false)
|
829
|
+
scratch.set_custom_method(klass_obj, :autoload, Builtin.method(:kernel_autoload), false)
|
725
830
|
scratch.set_custom_method(klass_module, :autoload, Builtin.method(:module_autoload))
|
726
831
|
|
727
832
|
# remove BasicObject#method_missing
|