mirror of
https://github.com/rubyjs/therubyrhino
synced 2023-03-27 23:21:34 -04:00
JS style function call argument slicing/filling + fn.length fix to be always >= 0
This commit is contained in:
parent
0e2274a685
commit
8e6b51cfb4
2 changed files with 66 additions and 5 deletions
|
@ -162,7 +162,8 @@ module Rhino
|
|||
|
||||
# override int BaseFunction#getLength()
|
||||
def getLength
|
||||
@callable.arity
|
||||
arity = @callable.arity
|
||||
arity < 0 ? 0 : arity # -1 for `lambda { 42 }`
|
||||
end
|
||||
|
||||
# #deprecated int BaseFunction#getArity()
|
||||
|
@ -187,7 +188,16 @@ module Rhino
|
|||
# override Object BaseFunction#call(Context context, Scriptable scope,
|
||||
# Scriptable thisObj, Object[] args)
|
||||
def call(context, scope, this, args)
|
||||
rb_args = Rhino.args_to_ruby(args.to_a)
|
||||
args = args.to_a # java.lang.Object[] -> Array
|
||||
# JS function style :
|
||||
if (arity = @callable.arity) >= 0
|
||||
if args.size > arity # omit 'redundant' arguments
|
||||
args = args.slice(0, arity)
|
||||
elsif arity > args.size # fill 'missing' arguments
|
||||
(arity - args.size).times { args.push(nil) }
|
||||
end
|
||||
end
|
||||
rb_args = Rhino.args_to_ruby(args)
|
||||
begin
|
||||
result = @callable.call(*rb_args)
|
||||
rescue => e
|
||||
|
@ -218,7 +228,8 @@ module Rhino
|
|||
|
||||
# override int BaseFunction#getLength()
|
||||
def getLength
|
||||
@klass.instance_method(:initialize).arity
|
||||
arity = @klass.instance_method(:initialize).arity
|
||||
arity < 0 ? 0 : arity # -1 for `initialize(*args)`
|
||||
end
|
||||
|
||||
# override boolean Scriptable#hasInstance(Scriptable instance);
|
||||
|
@ -231,7 +242,7 @@ module Rhino
|
|||
end
|
||||
|
||||
def self.cache(key)
|
||||
fetch(key) || write(key, yield)
|
||||
fetch(key) || store(key, yield)
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -245,7 +256,7 @@ module Rhino
|
|||
ref ? ref.get : nil
|
||||
end
|
||||
|
||||
def self.write(key, value)
|
||||
def self.store(key, value)
|
||||
@@cache.put(key, java.lang.ref.WeakReference.new(value)) if @@cache
|
||||
value
|
||||
end
|
||||
|
|
|
@ -256,6 +256,38 @@ describe Rhino::Ruby::Function do
|
|||
rb_function.call(context, scope, this, args).should be_a(Rhino::JS::NativeArray)
|
||||
end
|
||||
|
||||
it "slices redundant args when delegating call" do
|
||||
klass = Class.new(Object) do
|
||||
def foo(a1)
|
||||
a1
|
||||
end
|
||||
end
|
||||
rb_function = Rhino::Ruby::Function.wrap method = klass.new.method(:foo)
|
||||
context = nil; scope = nil; this = nil
|
||||
|
||||
args = [ 1.to_java, 2.to_java, 3.to_java ].to_java; js_return = nil
|
||||
lambda { js_return = rb_function.call(context, scope, this, args) }.should_not raise_error
|
||||
js_return.should == 1
|
||||
end
|
||||
|
||||
it "fills missing args when delegating call" do
|
||||
klass = Class.new(Object) do
|
||||
def foo(a1, a2)
|
||||
[ a1, a2 ]
|
||||
end
|
||||
end
|
||||
rb_function = Rhino::Ruby::Function.wrap method = klass.new.method(:foo)
|
||||
context = nil; scope = nil; this = nil
|
||||
|
||||
args = [ 1.to_java ].to_java; js_return = nil
|
||||
lambda { js_return = rb_function.call(context, scope, this, args) }.should_not raise_error
|
||||
js_return.toArray.to_a.should == [ 1, nil ]
|
||||
|
||||
args = [ ].to_java; js_return = nil
|
||||
lambda { js_return = rb_function.call(context, scope, this, args) }.should_not raise_error
|
||||
js_return.toArray.to_a.should == [ nil, nil ]
|
||||
end
|
||||
|
||||
it "returns correct arity and length" do
|
||||
klass = Class.new(Object) do
|
||||
def foo(a1, a2)
|
||||
|
@ -267,6 +299,15 @@ describe Rhino::Ruby::Function do
|
|||
rb_function.getLength.should == 2
|
||||
end
|
||||
|
||||
it "reports arity and length of 0 for varargs" do
|
||||
klass = Class.new(Object) do
|
||||
def foo(*args); args; end
|
||||
end
|
||||
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
||||
rb_function.getArity.should == 0
|
||||
rb_function.getLength.should == 0
|
||||
end
|
||||
|
||||
describe 'with scope' do
|
||||
|
||||
before do
|
||||
|
@ -326,6 +367,15 @@ describe Rhino::Ruby::Constructor do
|
|||
rb_new.getLength.should == 0
|
||||
end
|
||||
|
||||
it "reports arity and length of 0 for varargs" do
|
||||
klass = Class.new do
|
||||
def initialize(*args); args; end
|
||||
end
|
||||
rb_new = Rhino::Ruby::Constructor.wrap klass
|
||||
rb_new.getArity.should == 0
|
||||
rb_new.getLength.should == 0
|
||||
end
|
||||
|
||||
describe 'with scope' do
|
||||
|
||||
before do
|
||||
|
|
Loading…
Reference in a new issue