mirror of
https://github.com/rubyjs/therubyrhino
synced 2023-03-27 23:21:34 -04:00
extract and reuse Scriptable get/has/put implementation across all ruby wrappers ...
This commit is contained in:
parent
ff18fb111d
commit
21434b05df
1 changed files with 78 additions and 71 deletions
|
@ -2,9 +2,71 @@
|
|||
module Rhino
|
||||
module Ruby
|
||||
|
||||
# shared JS::Scriptable implementation
|
||||
module Scriptable
|
||||
|
||||
# override Object Scriptable#get(String name, Scriptable start);
|
||||
# override Object Scriptable#get(int index, Scriptable start);
|
||||
def get(name, start)
|
||||
if name.is_a?(String)
|
||||
if unwrap.respond_to?(name)
|
||||
method = unwrap.method(name)
|
||||
if method.arity == 0 && # check if it is an attr_reader
|
||||
( unwrap.respond_to?("#{name}=") || unwrap.instance_variables.include?("@#{name}") )
|
||||
begin
|
||||
return Rhino.to_javascript(method.call, self)
|
||||
rescue => e
|
||||
raise Function.wrap_error(e)
|
||||
end
|
||||
else
|
||||
return Function.wrap(unwrap.method(name))
|
||||
end
|
||||
end
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
# override boolean Scriptable#has(String name, Scriptable start);
|
||||
# override boolean Scriptable#has(int index, Scriptable start);
|
||||
def has(name, start)
|
||||
if name.is_a?(String)
|
||||
if unwrap.respond_to?(name) ||
|
||||
unwrap.respond_to?("#{name}=") # might have a writer but no reader
|
||||
return true
|
||||
end
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
# override void Scriptable#put(String name, Scriptable start, Object value);
|
||||
# override void Scriptable#put(int index, Scriptable start, Object value);
|
||||
def put(name, start, value)
|
||||
if name.is_a?(String)
|
||||
if unwrap.respond_to?(set_name = "#{name}=")
|
||||
return unwrap.send(set_name, Rhino.to_ruby(value))
|
||||
end
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
# override Object[] Scriptable#getIds();
|
||||
def getIds
|
||||
ids = []
|
||||
unwrap.public_methods(false).each do |name|
|
||||
name = name[0...-1] if name[-1, 1] == '=' # 'foo=' ... 'foo'
|
||||
name = name.to_java # java.lang.String
|
||||
ids << name unless ids.include?(name)
|
||||
end
|
||||
super.each { |id| ids.unshift(id) }
|
||||
ids.to_java
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Object < JS::ScriptableObject
|
||||
include JS::Wrapper
|
||||
|
||||
include Scriptable
|
||||
|
||||
# wrap an arbitrary (ruby) object
|
||||
def self.wrap(object, scope = nil)
|
||||
Rhino::Ruby.cache(object) { new(object, scope) }
|
||||
|
@ -13,10 +75,7 @@ module Rhino
|
|||
def initialize(object, scope)
|
||||
super()
|
||||
@ruby = object
|
||||
if scope
|
||||
JS::ScriptRuntime.setObjectProtoAndParent(self, scope)
|
||||
setPrototype(JS::ScriptableObject.getObjectPrototype(scope)) unless getPrototype
|
||||
end
|
||||
@scope = scope
|
||||
end
|
||||
|
||||
# abstract Object Wrapper#unwrap();
|
||||
|
@ -33,71 +92,28 @@ module Rhino
|
|||
"[ruby #{getClassName}]" # [object User]
|
||||
end
|
||||
|
||||
# override Object Scriptable#get(String name, Scriptable start);
|
||||
# override Object Scriptable#get(int index, Scriptable start);
|
||||
def get(name, start)
|
||||
if name.is_a?(String)
|
||||
if @ruby.respond_to?(name)
|
||||
method = @ruby.method(name)
|
||||
if method.arity == 0 && # check if it is an attr_reader
|
||||
( @ruby.respond_to?("#{name}=") || @ruby.instance_variables.include?("@#{name}") )
|
||||
begin
|
||||
return Rhino.to_javascript(method.call, self)
|
||||
rescue => e
|
||||
raise Function.wrap_error(e)
|
||||
end
|
||||
else
|
||||
return Function.wrap(@ruby.method(name))
|
||||
end
|
||||
end
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
# override boolean Scriptable#has(String name, Scriptable start);
|
||||
# override boolean Scriptable#has(int index, Scriptable start);
|
||||
def has(name, start)
|
||||
if name.is_a?(String)
|
||||
if @ruby.respond_to?(name) ||
|
||||
@ruby.respond_to?("#{name}=") # might have a writer but no reader
|
||||
return true
|
||||
end
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
# override void Scriptable#put(String name, Scriptable start, Object value);
|
||||
# override void Scriptable#put(int index, Scriptable start, Object value);
|
||||
def put(name, start, value)
|
||||
if name.is_a?(String)
|
||||
if @ruby.respond_to?(set_name = "#{name}=")
|
||||
return @ruby.send(set_name, Rhino.to_ruby(value))
|
||||
end
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
# override Object[] Scriptable#getIds();
|
||||
def getIds
|
||||
ids = []
|
||||
@ruby.public_methods(false).each do |name|
|
||||
name = name[0...-1] if name[-1, 1] == '=' # 'foo=' ... 'foo'
|
||||
name = name.to_java # java.lang.String
|
||||
ids << name unless ids.include?(name)
|
||||
end
|
||||
super.each { |id| ids.unshift(id) }
|
||||
ids.to_java
|
||||
end
|
||||
|
||||
# protected Object ScriptableObject#equivalentValues(Object value)
|
||||
def equivalentValues(other) # JS == operator
|
||||
other.is_a?(Object) && unwrap.eql?(other.unwrap)
|
||||
end
|
||||
|
||||
# override Scriptable Scriptable#getPrototype();
|
||||
def getPrototype
|
||||
# TODO needs to be revisited to that ruby.constructor works ...
|
||||
if ! (proto = super) && @scope
|
||||
JS::ScriptRuntime.setObjectProtoAndParent(self, @scope)
|
||||
unless proto = super
|
||||
setPrototype(proto = JS::ScriptableObject.getObjectPrototype(@scope))
|
||||
end
|
||||
end
|
||||
proto
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Function < JS::BaseFunction
|
||||
|
||||
include Scriptable
|
||||
|
||||
# wrap a callable (Method/Proc)
|
||||
def self.wrap(callable, scope = nil)
|
||||
Rhino::Ruby.cache(callable) { new(callable, scope) }
|
||||
|
@ -141,15 +157,6 @@ module Rhino
|
|||
unwrap.to_s == other.unwrap.to_s # "#<Method: Foo#bar>"
|
||||
end
|
||||
|
||||
# override Object ScriptableObject#getPrototype()
|
||||
def getPrototype
|
||||
unless proto = super
|
||||
#proto = ScriptableObject.getFunctionPrototype(getParentScope)
|
||||
#setPrototype(proto)
|
||||
end
|
||||
proto
|
||||
end
|
||||
|
||||
# override Object BaseFunction#call(Context context, Scriptable scope,
|
||||
# Scriptable thisObj, Object[] args)
|
||||
def call(context, scope, this, args)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue