mirror of
https://github.com/rubyjs/therubyrhino
synced 2023-03-27 23:21:34 -04:00
pass a scope to initialize for all ruby wrapper classes and attempt to initialize parent scope and prototype whenever it is present; override BaseFunction's #getLength and #getFunctionName for RubyFunction
This commit is contained in:
parent
21f62eb245
commit
cdf770d95b
5 changed files with 94 additions and 15 deletions
|
@ -89,7 +89,7 @@ class Java::OrgMozillaJavascript::ScriptableObject
|
|||
def method_missing(name, *args)
|
||||
s_name = name.to_s
|
||||
if s_name[-1, 1] == '=' && args.size == 1 # writer -> JS put
|
||||
self[ s_name[0...-1] ] = args[0]
|
||||
self[ s_name[0...-1] ] = args[0]
|
||||
else
|
||||
property = ScriptableObject.getProperty(self, s_name)
|
||||
if property && property != Scriptable::NOT_FOUND
|
||||
|
|
|
@ -5,13 +5,17 @@ module Rhino
|
|||
include JS::Wrapper
|
||||
|
||||
# wrap an arbitrary (ruby) object
|
||||
def self.wrap(object)
|
||||
new(object)
|
||||
def self.wrap(object, scope = nil)
|
||||
new(object, scope)
|
||||
end
|
||||
|
||||
def initialize(object)
|
||||
def initialize(object, scope)
|
||||
super()
|
||||
@ruby = object
|
||||
if scope
|
||||
JS::ScriptRuntime.setObjectProtoAndParent(self, scope)
|
||||
setPrototype(JS::ScriptableObject.getObjectPrototype(scope)) unless getPrototype
|
||||
end
|
||||
end
|
||||
|
||||
# abstract Object Wrapper#unwrap();
|
||||
|
@ -42,7 +46,7 @@ module Rhino
|
|||
raise RubyFunction.wrap_error(e)
|
||||
end
|
||||
else
|
||||
return RubyFunction.new(@ruby.method(name))
|
||||
return RubyFunction.wrap(@ruby.method(name))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -94,17 +98,33 @@ module Rhino
|
|||
class RubyFunction < JS::BaseFunction
|
||||
|
||||
# wrap a callable (Method/Proc)
|
||||
def self.wrap(callable)
|
||||
new(callable)
|
||||
def self.wrap(callable, scope = nil)
|
||||
new(callable, scope)
|
||||
end
|
||||
|
||||
def self.wrap_error(e)
|
||||
JS::WrappedException.new(org.jruby.exceptions.RaiseException.new(e))
|
||||
end
|
||||
|
||||
def initialize(callable)
|
||||
def initialize(callable, scope)
|
||||
super()
|
||||
@callable = callable
|
||||
JS::ScriptRuntime.setFunctionProtoAndParent(self, scope) if scope
|
||||
end
|
||||
|
||||
# override int BaseFunction#getLength()
|
||||
def getLength
|
||||
@callable.arity
|
||||
end
|
||||
|
||||
# #deprecated int BaseFunction#getArity()
|
||||
def getArity
|
||||
getLength
|
||||
end
|
||||
|
||||
# override String BaseFunction#getFunctionName()
|
||||
def getFunctionName
|
||||
@callable.is_a?(Proc) ? "" : @callable.name
|
||||
end
|
||||
|
||||
def unwrap
|
||||
|
@ -148,12 +168,12 @@ module Rhino
|
|||
include JS::Wrapper
|
||||
|
||||
# wrap a ruby class as as constructor function
|
||||
def self.wrap(klass)
|
||||
new(klass)
|
||||
def self.wrap(klass, scope = nil)
|
||||
new(klass, scope)
|
||||
end
|
||||
|
||||
def initialize(klass)
|
||||
super(klass.method(:new))
|
||||
def initialize(klass, scope)
|
||||
super(klass.method(:new), scope)
|
||||
@klass = klass
|
||||
end
|
||||
|
||||
|
|
|
@ -20,10 +20,10 @@ module Rhino
|
|||
when Array then array_to_javascript(object, scope)
|
||||
when Hash then hash_to_javascript(object, scope)
|
||||
when Time then time_to_javascript(object, scope)
|
||||
when Proc, Method then RubyFunction.wrap(object)
|
||||
when Proc, Method then RubyFunction.wrap(object, scope)
|
||||
when JS::Scriptable then object
|
||||
when Class then RubyConstructor.wrap(object)
|
||||
else RubyObject.wrap(object)
|
||||
when Class then RubyConstructor.wrap(object, scope)
|
||||
else RubyObject.wrap(object, scope)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -37,4 +37,39 @@ describe Rhino::RubyFunction do
|
|||
rb_function.call(context, scope, this, args).should be_a(Rhino::JS::NativeArray)
|
||||
end
|
||||
|
||||
it "returns correct arity and length" do
|
||||
klass = Class.new(Object) do
|
||||
def foo(a1, a2)
|
||||
a1 || a2
|
||||
end
|
||||
end
|
||||
rb_function = Rhino::RubyFunction.wrap klass.new.method(:foo)
|
||||
rb_function.getArity.should == 2
|
||||
rb_function.getLength.should == 2
|
||||
end
|
||||
|
||||
describe 'with scope' do
|
||||
|
||||
before do
|
||||
factory = Rhino::JS::ContextFactory.new
|
||||
context = nil
|
||||
factory.call do |ctx|
|
||||
context = ctx
|
||||
@scope = context.initStandardObjects(nil, false)
|
||||
end
|
||||
factory.enterContext(context)
|
||||
end
|
||||
|
||||
after do
|
||||
Rhino::JS::Context.exit
|
||||
end
|
||||
|
||||
it "sets up correct prototype" do
|
||||
rb_function = Rhino::RubyFunction.wrap 'foo'.method(:concat), @scope
|
||||
rb_function.getPrototype.should_not be(nil)
|
||||
rb_function.getPrototype.should be_a(Rhino::JS::Function)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -121,4 +121,28 @@ describe Rhino::RubyObject do
|
|||
rb_object.getIds.to_a.should_not include('foo=')
|
||||
end
|
||||
|
||||
describe 'with scope' do
|
||||
|
||||
before do
|
||||
factory = Rhino::JS::ContextFactory.new
|
||||
context = nil
|
||||
factory.call do |ctx|
|
||||
context = ctx
|
||||
@scope = context.initStandardObjects(nil, false)
|
||||
end
|
||||
factory.enterContext(context)
|
||||
end
|
||||
|
||||
after do
|
||||
Rhino::JS::Context.exit
|
||||
end
|
||||
|
||||
it "sets up correct prototype" do
|
||||
rb_object = Rhino::RubyObject.wrap UII.new, @scope
|
||||
rb_object.getPrototype.should_not be(nil)
|
||||
rb_object.getPrototype.should be_a(Rhino::JS::NativeObject)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in a new issue