Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 36 additions & 13 deletions lib/typeprof/core/builtin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -180,21 +180,44 @@ def method_call(changes, node, ty, a_args, ret)
end
end

def kernel_send(changes, node, ty, a_args, ret)
return false if a_args.positionals.empty?
# Re-run this box when the first positional argument's types change
changes.add_edge(@genv, a_args.positionals[0], changes.target)
send_a_args = ActualArguments.new(
a_args.positionals[1..],
a_args.splat_flags[1..],
a_args.keywords,
a_args.block,
)
a_args.positionals[0].each_type do |sym_ty|
if sym_ty.is_a?(Type::Symbol)
recv = Source.new(ty)
box = changes.add_method_call_box(@genv, recv, sym_ty.sym, send_a_args, false)
changes.add_edge(@genv, box.ret, ret)
end
end
true
end

def deploy
{
class_new: [[:Class], false, :new],
object_class: [[:Object], false, :class],
proc_call: [[:Proc], false, :call],
array_aref: [[:Array], false, :[]],
array_aset: [[:Array], false, :[]=],
array_push: [[:Array], false, :<<],
hash_aref: [[:Hash], false, :[]],
hash_aset: [[:Hash], false, :[]=],
object_method: [[:Kernel], false, :method],
method_call: [[:Method], false, :call],
}.each do |key, (cpath, singleton, mid)|
[
[method(:class_new), [:Class], false, :new],
[method(:object_class), [:Object], false, :class],
[method(:proc_call), [:Proc], false, :call],
[method(:array_aref), [:Array], false, :[]],
[method(:array_aset), [:Array], false, :[]=],
[method(:array_push), [:Array], false, :<<],
[method(:hash_aref), [:Hash], false, :[]],
[method(:hash_aset), [:Hash], false, :[]=],
[method(:object_method), [:Kernel], false, :method],
[method(:method_call), [:Method], false, :call],
[method(:kernel_send), [:BasicObject], false, :__send__],
[method(:kernel_send), [:Kernel], false, :public_send],
[method(:kernel_send), [:Kernel], false, :send],
].each do |builtin, cpath, singleton, mid|
me = @genv.resolve_method(cpath, singleton, mid)
me.builtin = method(key)
me.builtin = builtin
end
end
end
Expand Down
73 changes: 73 additions & 0 deletions scenario/method/send.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
## update
class Foo
def bar(n)
n
end

def test
__send__(:bar, 1)
end
end

## assert
class Foo
def bar: (Integer) -> Integer
def test: -> Integer
end

## update
class Foo2
def greet(s)
s
end

def test
public_send(:greet, "hello")
end
end

## assert
class Foo2
def greet: (String) -> String
def test: -> String
end

## update
class Foo3
def add(a, b)
a
end

def test
send(:add, 1, 2)
end
end

## assert
class Foo3
def add: (Integer, Integer) -> Integer
def test: -> Integer
end

## update
class Foo4
def foo(n)
n
end

def bar(n)
n.to_s
end

def test
ary = [:foo, :bar]
ary.each { send(it, 1) }
end
end

## assert
class Foo4
def foo: (Integer) -> Integer
def bar: (Integer) -> String
def test: -> Array[:bar | :foo]
end