Skip to content

Commit c1f0dbe

Browse files
committed
Add builtin support for Kernel#send, __send__, and public_send
1 parent ae070ab commit c1f0dbe

2 files changed

Lines changed: 109 additions & 13 deletions

File tree

lib/typeprof/core/builtin.rb

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -180,21 +180,44 @@ def method_call(changes, node, ty, a_args, ret)
180180
end
181181
end
182182

183+
def kernel_send(changes, node, ty, a_args, ret)
184+
return false if a_args.positionals.empty?
185+
# Re-run this box when the first positional argument's types change
186+
changes.add_edge(@genv, a_args.positionals[0], changes.target)
187+
send_a_args = ActualArguments.new(
188+
a_args.positionals[1..],
189+
a_args.splat_flags[1..],
190+
a_args.keywords,
191+
a_args.block,
192+
)
193+
a_args.positionals[0].each_type do |sym_ty|
194+
if sym_ty.is_a?(Type::Symbol)
195+
recv = Source.new(ty)
196+
box = changes.add_method_call_box(@genv, recv, sym_ty.sym, send_a_args, false)
197+
changes.add_edge(@genv, box.ret, ret)
198+
end
199+
end
200+
true
201+
end
202+
183203
def deploy
184-
{
185-
class_new: [[:Class], false, :new],
186-
object_class: [[:Object], false, :class],
187-
proc_call: [[:Proc], false, :call],
188-
array_aref: [[:Array], false, :[]],
189-
array_aset: [[:Array], false, :[]=],
190-
array_push: [[:Array], false, :<<],
191-
hash_aref: [[:Hash], false, :[]],
192-
hash_aset: [[:Hash], false, :[]=],
193-
object_method: [[:Kernel], false, :method],
194-
method_call: [[:Method], false, :call],
195-
}.each do |key, (cpath, singleton, mid)|
204+
[
205+
[method(:class_new), [:Class], false, :new],
206+
[method(:object_class), [:Object], false, :class],
207+
[method(:proc_call), [:Proc], false, :call],
208+
[method(:array_aref), [:Array], false, :[]],
209+
[method(:array_aset), [:Array], false, :[]=],
210+
[method(:array_push), [:Array], false, :<<],
211+
[method(:hash_aref), [:Hash], false, :[]],
212+
[method(:hash_aset), [:Hash], false, :[]=],
213+
[method(:object_method), [:Kernel], false, :method],
214+
[method(:method_call), [:Method], false, :call],
215+
[method(:kernel_send), [:BasicObject], false, :__send__],
216+
[method(:kernel_send), [:Kernel], false, :public_send],
217+
[method(:kernel_send), [:Kernel], false, :send],
218+
].each do |builtin, cpath, singleton, mid|
196219
me = @genv.resolve_method(cpath, singleton, mid)
197-
me.builtin = method(key)
220+
me.builtin = builtin
198221
end
199222
end
200223
end

scenario/method/send.rb

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
## update
2+
class Foo
3+
def bar(n)
4+
n
5+
end
6+
7+
def test
8+
__send__(:bar, 1)
9+
end
10+
end
11+
12+
## assert
13+
class Foo
14+
def bar: (Integer) -> Integer
15+
def test: -> Integer
16+
end
17+
18+
## update
19+
class Foo2
20+
def greet(s)
21+
s
22+
end
23+
24+
def test
25+
public_send(:greet, "hello")
26+
end
27+
end
28+
29+
## assert
30+
class Foo2
31+
def greet: (String) -> String
32+
def test: -> String
33+
end
34+
35+
## update
36+
class Foo3
37+
def add(a, b)
38+
a
39+
end
40+
41+
def test
42+
send(:add, 1, 2)
43+
end
44+
end
45+
46+
## assert
47+
class Foo3
48+
def add: (Integer, Integer) -> Integer
49+
def test: -> Integer
50+
end
51+
52+
## update
53+
class Foo4
54+
def foo(n)
55+
n
56+
end
57+
58+
def bar(n)
59+
n.to_s
60+
end
61+
62+
def test
63+
ary = [:foo, :bar]
64+
ary.each { send(it, 1) }
65+
end
66+
end
67+
68+
## assert
69+
class Foo4
70+
def foo: (Integer) -> Integer
71+
def bar: (Integer) -> String
72+
def test: -> Array[:bar | :foo]
73+
end

0 commit comments

Comments
 (0)