diff --git a/js/rhino/build.properties b/js/rhino/build.properties index 42147dcd740..7592d81ba85 100644 --- a/js/rhino/build.properties +++ b/js/rhino/build.properties @@ -32,9 +32,9 @@ name: rhino Name: Rhino -version: 1_6R1 +version: 1_6R2pre # See Context#getImplementationVersion() for format of this! -implementation.version: Rhino 1.6 release 1 ${implementation.date} +implementation.version: Rhino 1.6 release 2 ${implementation.date} build.dir: build rhino.jar: js.jar diff --git a/js/rhino/src/org/mozilla/javascript/FunctionObject.java b/js/rhino/src/org/mozilla/javascript/FunctionObject.java index b7a4aea7cd2..4f524071e1b 100644 --- a/js/rhino/src/org/mozilla/javascript/FunctionObject.java +++ b/js/rhino/src/org/mozilla/javascript/FunctionObject.java @@ -288,6 +288,14 @@ public class FunctionObject extends BaseFunction return found; } + /** + * Returns all public methods declared by the specified class. This excludes + * inherited methods. + * + * @param clazz the class from which to pull public declared methods + * @return the public methods declared in the specified class + * @see Class#getDeclaredMethods() + */ static Method[] getMethodList(Class clazz) { Method[] methods = null; try { diff --git a/js/rhino/src/org/mozilla/javascript/ScriptableObject.java b/js/rhino/src/org/mozilla/javascript/ScriptableObject.java index 57d7e716cbe..497321cb0cc 100644 --- a/js/rhino/src/org/mozilla/javascript/ScriptableObject.java +++ b/js/rhino/src/org/mozilla/javascript/ScriptableObject.java @@ -711,9 +711,9 @@ public abstract class ScriptableObject implements Scriptable, Serializable, * argument will be passed, along with the newly created constructor and * the newly created prototype.

* - * @param scope The scope in which to define the constructor + * @param scope The scope in which to define the constructor. * @param clazz The Java class to use to define the JavaScript objects - * and properties + * and properties. * @exception IllegalAccessException if access is not available * to a reflected class member * @exception InstantiationException if unable to instantiate @@ -729,7 +729,7 @@ public abstract class ScriptableObject implements Scriptable, Serializable, throws IllegalAccessException, InstantiationException, InvocationTargetException { - defineClass(scope, clazz, false); + defineClass(scope, clazz, false, false); } /** @@ -742,10 +742,10 @@ public abstract class ScriptableObject implements Scriptable, Serializable, * the current ECMA/ISO language specification, but is likely for * the next version. * - * @param scope The scope in which to define the constructor + * @param scope The scope in which to define the constructor. * @param clazz The Java class to use to define the JavaScript objects * and properties. The class must implement Scriptable. - * @param sealed whether or not to create sealed standard objects that + * @param sealed Whether or not to create sealed standard objects that * cannot be modified. * @exception IllegalAccessException if access is not available * to a reflected class member @@ -759,6 +759,41 @@ public abstract class ScriptableObject implements Scriptable, Serializable, boolean sealed) throws IllegalAccessException, InstantiationException, InvocationTargetException + { + defineClass(scope, clazz, sealed, false); + } + + /** + * Defines JavaScript objects from a Java class, optionally + * allowing sealing and mapping of Java inheritance to JavaScript + * prototype-based inheritance. + * + * Similar to defineClass(Scriptable scope, Class clazz) + * except that sealing and inheritance mapping are allowed. An object + * that is sealed cannot have properties added or removed. Note that + * sealing is not allowed in the current ECMA/ISO language specification, + * but is likely for the next version. + * + * @param scope The scope in which to define the constructor. + * @param clazz The Java class to use to define the JavaScript objects + * and properties. The class must implement Scriptable. + * @param sealed Whether or not to create sealed standard objects that + * cannot be modified. + * @param mapInheritance Whether or not to map Java inheritance to + * JavaScript prototype-based inheritance. + * @return the class name for the prototype of the specified class + * @exception IllegalAccessException if access is not available + * to a reflected class member + * @exception InstantiationException if unable to instantiate + * the named class + * @exception InvocationTargetException if an exception is thrown + * during execution of methods of the named class + * @since 1.6R2 + */ + public static String defineClass(Scriptable scope, Class clazz, + boolean sealed, boolean mapInheritance) + throws IllegalAccessException, InstantiationException, + InvocationTargetException { Method[] methods = FunctionObject.getMethodList(clazz); for (int i=0; i < methods.length; i++) { @@ -775,7 +810,7 @@ public abstract class ScriptableObject implements Scriptable, Serializable, Object args[] = { Context.getContext(), scope, sealed ? Boolean.TRUE : Boolean.FALSE }; method.invoke(null, args); - return; + return null; } if (parmTypes.length == 1 && parmTypes[0] == ScriptRuntime.ScriptableClass && @@ -783,7 +818,7 @@ public abstract class ScriptableObject implements Scriptable, Serializable, { Object args[] = { scope }; method.invoke(null, args); - return; + return null; } } @@ -804,11 +839,26 @@ public abstract class ScriptableObject implements Scriptable, Serializable, "msg.zero.arg.ctor", clazz.getName()); } - Scriptable proto = (Scriptable) - protoCtor.newInstance(ScriptRuntime.emptyArgs); - proto.setPrototype(getObjectPrototype(scope)); + Scriptable proto = (Scriptable) protoCtor.newInstance(ScriptRuntime.emptyArgs); String className = proto.getClassName(); + // Set the prototype's prototype, trying to map Java inheritance to JS + // prototype-based inheritance if requested to do so. + Scriptable superProto = null; + if (mapInheritance) { + Class superClass = clazz.getSuperclass(); + if (ScriptRuntime.ScriptableClass.isAssignableFrom(superClass)) { + String name = ScriptableObject.defineClass(scope, superClass, sealed, mapInheritance); + if (name != null) { + superProto = ScriptableObject.getClassPrototype(scope, name); + } + } + } + if (superProto == null) { + superProto = ScriptableObject.getObjectPrototype(scope); + } + proto.setPrototype(superProto); + // Find out whether there are any methods that begin with // "js". If so, then only methods that begin with special // prefixes will be defined as JavaScript entities. @@ -918,18 +968,21 @@ public abstract class ScriptableObject implements Scriptable, Serializable, } } + // Call user code to complete initialization if necessary. if (finishInit != null) { - // call user code to complete the initialization Object[] finishArgs = { scope, ctor, proto }; finishInit.invoke(null, finishArgs); } + // Seal the object if necessary. if (sealed) { ctor.sealObject(); if (proto instanceof ScriptableObject) { ((ScriptableObject) proto).sealObject(); } } + + return className; } /**