Skip to content

Commit

Permalink
Merge pull request #532 from ruby/curry
Browse files Browse the repository at this point in the history
Generate hook method with required args
  • Loading branch information
soutaro authored Dec 19, 2020
2 parents 78d04a2 + b3b63c6 commit 067c357
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 4 deletions.
17 changes: 13 additions & 4 deletions lib/rbs/test/hook.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,19 @@ def self.setup_alias_method_chain(klass, target, random:)
end
end

def self.hook_method_source(prefix, method_name, key, random:)
def self.hook_method_source(prefix, method_name, key, random:, params:)
with_name, without_name = alias_names(method_name, random)
full_method_name = "#{prefix}#{method_name}"

param_source = params.take_while {|param| param[0] == :req }.map(&:last) + ["*rest_args_#{random}"]

RBS.logger.debug {
"Generating method definition: def #{with_name}(#{param_source.join(", ")}, &block) ..."
}

[__LINE__ + 1, <<RUBY]
def #{with_name}(*args, &block)
def #{with_name}(#{param_source.join(", ")}, &block)
args = [#{param_source.join(", ")}]
::RBS.logger.debug { "#{full_method_name} with arguments: [" + args.map(&:inspect).join(", ") + "]" }
begin
Expand Down Expand Up @@ -171,15 +178,17 @@ def #{with_name}(*args, &block)

def self.hook_instance_method(klass, method, key:)
random = SecureRandom.hex(4)
line, source = hook_method_source("#{klass}#", method, key, random: random)
params = klass.instance_method(method).parameters
line, source = hook_method_source("#{klass}#", method, key, random: random, params: params)

klass.module_eval(source, __FILE__, line)
setup_alias_method_chain klass, method, random: random
end

def self.hook_singleton_method(klass, method, key:)
random = SecureRandom.hex(4)
line, source = hook_method_source("#{klass}.",method, key, random: random)
params = klass.method(method).parameters
line, source = hook_method_source("#{klass}.",method, key, random: random, params: params)

klass.singleton_class.module_eval(source, __FILE__, line)
setup_alias_method_chain klass.singleton_class, method, random: random
Expand Down
34 changes: 34 additions & 0 deletions test/rbs/test/runtime_test_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,40 @@ def call(val, &block)
RUBY
end

def test_method_curry
assert_test_success(other_env: { 'RBS_TEST_TARGET' => "A" }, rbs_content: <<RBS, ruby_content: <<'RUBY')
class A
def on_object: (Integer, String) -> void
end
RBS
class A
def on_object(x, y)
pp(x: x, y: y)
end
end
STDOUT.puts A.new.method(:on_object).curry[1][""]
RUBY
end

def test_missing_required_args
output = refute_test_success(ruby_content: <<RUBY, rbs_content: <<RBS)
class Hello
def world(x)
end
end
Hello.new.world()
RUBY
class Hello
def world: (Integer) -> void
end
RBS

# Ruby's standard ArgumentError is raised if required argument is not given.
assert_match(/\(ArgumentError\)/, output)
end

def test_method_callbacks
assert_test_success(other_env: { 'RBS_TEST_TARGET' => "Callbacks" }, rbs_content: <<RBS, ruby_content: <<'RUBY')
module Callbacks
Expand Down

0 comments on commit 067c357

Please sign in to comment.