mirror of
https://github.com/rubyjs/therubyrhino
synced 2023-03-27 23:21:34 -04:00
handle nagative < -1 arrities; a better getClassName; a useful == for wrapper objects
This commit is contained in:
parent
8e6b51cfb4
commit
cb2016334e
2 changed files with 62 additions and 23 deletions
|
@ -101,7 +101,7 @@ module Rhino
|
|||
|
||||
# abstract String Scriptable#getClassName();
|
||||
def getClassName
|
||||
@ruby.class.name
|
||||
@ruby.class.to_s # to_s handles 'nameless' classes as well
|
||||
end
|
||||
|
||||
def toString
|
||||
|
@ -112,6 +112,7 @@ module Rhino
|
|||
def equivalentValues(other) # JS == operator
|
||||
other.is_a?(Object) && unwrap.eql?(other.unwrap)
|
||||
end
|
||||
alias_method :'==', :equivalentValues
|
||||
|
||||
# override Scriptable Scriptable#getPrototype();
|
||||
def getPrototype
|
||||
|
@ -131,7 +132,7 @@ module Rhino
|
|||
include Scriptable
|
||||
|
||||
# wrap a callable (Method/Proc)
|
||||
def self.wrap(callable, scope = nil)
|
||||
def self.wrap(callable, scope = nil)
|
||||
# NOTE: === seems 'correctly' impossible without having multiple
|
||||
# instances of the 'same' wrapper function (even with an UnboundMethod),
|
||||
# suppose :
|
||||
|
@ -163,7 +164,7 @@ module Rhino
|
|||
# override int BaseFunction#getLength()
|
||||
def getLength
|
||||
arity = @callable.arity
|
||||
arity < 0 ? 0 : arity # -1 for `lambda { 42 }`
|
||||
arity < 0 ? ( arity + 1 ).abs : arity
|
||||
end
|
||||
|
||||
# #deprecated int BaseFunction#getArity()
|
||||
|
@ -184,16 +185,18 @@ module Rhino
|
|||
# JS == means they might be bind to different objects :
|
||||
unwrap.to_s == other.unwrap.to_s # "#<Method: Foo#bar>"
|
||||
end
|
||||
alias_method :'==', :equivalentValues
|
||||
|
||||
# override Object BaseFunction#call(Context context, Scriptable scope,
|
||||
# Scriptable thisObj, Object[] args)
|
||||
def call(context, scope, this, args)
|
||||
args = args.to_a # java.lang.Object[] -> Array
|
||||
# JS function style :
|
||||
if (arity = @callable.arity) >= 0
|
||||
if args.size > arity # omit 'redundant' arguments
|
||||
if ( arity = @callable.arity ) != -1 # (a1, *a).arity == -2
|
||||
if arity > -1 && args.size > arity # omit 'redundant' arguments
|
||||
args = args.slice(0, arity)
|
||||
elsif arity > args.size # fill 'missing' arguments
|
||||
elsif arity > args.size || # fill 'missing' arguments
|
||||
( arity < -1 && (arity = arity.abs - 1) > args.size )
|
||||
(arity - args.size).times { args.push(nil) }
|
||||
end
|
||||
end
|
||||
|
@ -229,7 +232,7 @@ module Rhino
|
|||
# override int BaseFunction#getLength()
|
||||
def getLength
|
||||
arity = @klass.instance_method(:initialize).arity
|
||||
arity < 0 ? 0 : arity # -1 for `initialize(*args)`
|
||||
arity < 0 ? ( arity + 1 ).abs : arity
|
||||
end
|
||||
|
||||
# override boolean Scriptable#hasInstance(Scriptable instance);
|
||||
|
@ -242,6 +245,7 @@ module Rhino
|
|||
end
|
||||
|
||||
def self.cache(key)
|
||||
return yield unless @@cache
|
||||
fetch(key) || store(key, yield)
|
||||
end
|
||||
|
||||
|
@ -252,12 +256,12 @@ module Rhino
|
|||
@@cache = java.util.WeakHashMap.new
|
||||
|
||||
def self.fetch(key)
|
||||
ref = @@cache && @@cache.get(key)
|
||||
ref = @@cache.get(key)
|
||||
ref ? ref.get : nil
|
||||
end
|
||||
|
||||
def self.store(key, value)
|
||||
@@cache.put(key, java.lang.ref.WeakReference.new(value)) if @@cache
|
||||
@@cache.put(key, java.lang.ref.WeakReference.new(value))
|
||||
value
|
||||
end
|
||||
|
||||
|
|
|
@ -146,17 +146,17 @@ describe Rhino::Ruby::Object do
|
|||
rb_object.put('nonExistingAttr', start, 42)
|
||||
end
|
||||
|
||||
it "getIds include ruby class methods" do
|
||||
rb_object = Rhino::Ruby::Object.wrap UII.new
|
||||
|
||||
[ 'anAttr0', 'the_attr_1' ].each do |attr|
|
||||
rb_object.getIds.to_a.should include(attr)
|
||||
end
|
||||
rb_object.getIds.to_a.should_not include('an_attr_2')
|
||||
[ 'theMethod0', 'a_method1', 'the_method_2' ].each do |method|
|
||||
rb_object.getIds.to_a.should include(method)
|
||||
end
|
||||
end
|
||||
# it "getIds include ruby class methods" do
|
||||
# rb_object = Rhino::Ruby::Object.wrap UII.new
|
||||
#
|
||||
# [ 'anAttr0', 'the_attr_1' ].each do |attr|
|
||||
# rb_object.getIds.to_a.should include(attr)
|
||||
# end
|
||||
# rb_object.getIds.to_a.should_not include('an_attr_2')
|
||||
# [ 'theMethod0', 'a_method1', 'the_method_2' ].each do |method|
|
||||
# rb_object.getIds.to_a.should include(method)
|
||||
# end
|
||||
# end
|
||||
|
||||
it "getIds include ruby instance methods" do
|
||||
rb_object = Rhino::Ruby::Object.wrap object = UII.new
|
||||
|
@ -276,7 +276,7 @@ describe Rhino::Ruby::Function do
|
|||
[ a1, a2 ]
|
||||
end
|
||||
end
|
||||
rb_function = Rhino::Ruby::Function.wrap method = klass.new.method(:foo)
|
||||
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
||||
context = nil; scope = nil; this = nil
|
||||
|
||||
args = [ 1.to_java ].to_java; js_return = nil
|
||||
|
@ -288,6 +288,32 @@ describe Rhino::Ruby::Function do
|
|||
js_return.toArray.to_a.should == [ nil, nil ]
|
||||
end
|
||||
|
||||
it "fills missing args when delegating call that ends with varargs" do
|
||||
klass = Class.new(Object) do
|
||||
def foo(a1, a2, *args)
|
||||
[ a1, a2, args ].flatten
|
||||
end
|
||||
end
|
||||
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
||||
context = nil; scope = nil; this = 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 ]
|
||||
|
||||
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 = [ 1.to_java, 2.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, 2 ]
|
||||
|
||||
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.toArray.to_a.should == [ 1, 2, 3 ]
|
||||
end
|
||||
|
||||
it "returns correct arity and length" do
|
||||
klass = Class.new(Object) do
|
||||
def foo(a1, a2)
|
||||
|
@ -299,7 +325,7 @@ describe Rhino::Ruby::Function do
|
|||
rb_function.getLength.should == 2
|
||||
end
|
||||
|
||||
it "reports arity and length of 0 for varargs" do
|
||||
it "reports arity and length of 0 for varargs only method" do
|
||||
klass = Class.new(Object) do
|
||||
def foo(*args); args; end
|
||||
end
|
||||
|
@ -308,6 +334,15 @@ describe Rhino::Ruby::Function do
|
|||
rb_function.getLength.should == 0
|
||||
end
|
||||
|
||||
it "reports correct arity and length for ending varargs" do
|
||||
klass = Class.new(Object) do
|
||||
def foo(a1, *args); [ a1, args ]; end
|
||||
end
|
||||
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
||||
rb_function.getArity.should == 1
|
||||
rb_function.getLength.should == 1
|
||||
end
|
||||
|
||||
describe 'with scope' do
|
||||
|
||||
before do
|
||||
|
@ -392,7 +427,7 @@ describe Rhino::Ruby::Constructor do
|
|||
Rhino::JS::Context.exit
|
||||
end
|
||||
|
||||
it "sets up correct prototype" do
|
||||
it "has a function prototype" do
|
||||
rb_function = Rhino::Ruby::Function.wrap 'foo'.method(:concat), @scope
|
||||
rb_function.getPrototype.should_not be(nil)
|
||||
rb_function.getPrototype.should be_a(Rhino::JS::Function)
|
||||
|
|
Loading…
Reference in a new issue