1
0
Fork 0
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:
kares 2011-12-12 22:34:27 +01:00
parent 21f62eb245
commit cdf770d95b
5 changed files with 94 additions and 15 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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