⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scriptableobject.java

📁 這是一個javascript 的 interpreter是了解 web browser的好材料
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
    {        Context cx = null;        for (int i=0; i < 2; i++) {            boolean tryToString;            if (typeHint == ScriptRuntime.StringClass) {                tryToString = (i == 0);            } else {                tryToString = (i == 1);            }            String methodName;            Object[] args;            if (tryToString) {                methodName = "toString";                args = ScriptRuntime.emptyArgs;            } else {                methodName = "valueOf";                args = new Object[1];                String hint;                if (typeHint == null) {                    hint = "undefined";                } else if (typeHint == ScriptRuntime.StringClass) {                    hint = "string";                } else if (typeHint == ScriptRuntime.ScriptableClass) {                    hint = "object";                } else if (typeHint == ScriptRuntime.FunctionClass) {                    hint = "function";                } else if (typeHint == ScriptRuntime.BooleanClass                           || typeHint == Boolean.TYPE)                {                    hint = "boolean";                } else if (typeHint == ScriptRuntime.NumberClass ||                         typeHint == ScriptRuntime.ByteClass ||                         typeHint == Byte.TYPE ||                         typeHint == ScriptRuntime.ShortClass ||                         typeHint == Short.TYPE ||                         typeHint == ScriptRuntime.IntegerClass ||                         typeHint == Integer.TYPE ||                         typeHint == ScriptRuntime.FloatClass ||                         typeHint == Float.TYPE ||                         typeHint == ScriptRuntime.DoubleClass ||                         typeHint == Double.TYPE)                {                    hint = "number";                } else {                    throw Context.reportRuntimeError1(                        "msg.invalid.type", typeHint.toString());                }                args[0] = hint;            }            Object v = getProperty(object, methodName);            if (!(v instanceof Function))                continue;            Function fun = (Function) v;            if (cx == null)                cx = Context.getContext();            v = fun.call(cx, fun.getParentScope(), object, args);            if (v != null) {                if (!(v instanceof Scriptable)) {                    return v;                }                if (typeHint == ScriptRuntime.ScriptableClass                    || typeHint == ScriptRuntime.FunctionClass)                {                    return v;                }                if (tryToString && v instanceof Wrapper) {                    // Let a wrapped java.lang.String pass for a primitive                    // string.                    Object u = ((Wrapper)v).unwrap();                    if (u instanceof String)                        return u;                }            }        }        // fall through to error        String arg = (typeHint == null) ? "undefined" : typeHint.getName();        throw ScriptRuntime.typeError1("msg.default.value", arg);    }    /**     * Implements the instanceof operator.     *     * <p>This operator has been proposed to ECMA.     *     * @param instance The value that appeared on the LHS of the instanceof     *              operator     * @return true if "this" appears in value's prototype chain     *     */    public boolean hasInstance(Scriptable instance) {        // Default for JS objects (other than Function) is to do prototype        // chasing.  This will be overridden in NativeFunction and non-JS        // objects.        return ScriptRuntime.jsDelegatesTo(instance, this);    }        /**     * Emulate the SpiderMonkey (and Firefox) feature of allowing     * custom objects to avoid detection by normal "object detection"     * code patterns. This is used to implement document.all.     * See https://bugzilla.mozilla.org/show_bug.cgi?id=412247.     * This is an analog to JOF_DETECTING from SpiderMonkey; see     * https://bugzilla.mozilla.org/show_bug.cgi?id=248549.     * Other than this special case, embeddings should return false.     * @return true if this object should avoid object detection     * @since 1.7R1     */    public boolean avoidObjectDetection() {        return false;    }    /**     * Custom <tt>==</tt> operator.     * Must return {@link Scriptable#NOT_FOUND} if this object does not     * have custom equality operator for the given value,     * <tt>Boolean.TRUE</tt> if this object is equivalent to <tt>value</tt>,     * <tt>Boolean.FALSE</tt> if this object is not equivalent to     * <tt>value</tt>.     * <p>     * The default implementation returns Boolean.TRUE     * if <tt>this == value</tt> or {@link Scriptable#NOT_FOUND} otherwise.     * It indicates that by default custom equality is available only if     * <tt>value</tt> is <tt>this</tt> in which case true is returned.     */    protected Object equivalentValues(Object value)    {        return (this == value) ? Boolean.TRUE : Scriptable.NOT_FOUND;    }    /**     * Defines JavaScript objects from a Java class that implements Scriptable.     *     * If the given class has a method     * <pre>     * static void init(Context cx, Scriptable scope, boolean sealed);</pre>     *     * or its compatibility form     * <pre>     * static void init(Scriptable scope);</pre>     *     * then it is invoked and no further initialization is done.<p>     *     * However, if no such a method is found, then the class's constructors and     * methods are used to initialize a class in the following manner.<p>     *     * First, the zero-parameter constructor of the class is called to     * create the prototype. If no such constructor exists,     * a {@link EvaluatorException} is thrown. <p>     *     * Next, all methods are scanned for special prefixes that indicate that they     * have special meaning for defining JavaScript objects.     * These special prefixes are     * <ul>     * <li><code>jsFunction_</code> for a JavaScript function     * <li><code>jsStaticFunction_</code> for a JavaScript function that     *           is a property of the constructor     * <li><code>jsGet_</code> for a getter of a JavaScript property     * <li><code>jsSet_</code> for a setter of a JavaScript property     * <li><code>jsConstructor</code> for a JavaScript function that     *           is the constructor     * </ul><p>     *     * If the method's name begins with "jsFunction_", a JavaScript function     * is created with a name formed from the rest of the Java method name     * following "jsFunction_". So a Java method named "jsFunction_foo" will     * define a JavaScript method "foo". Calling this JavaScript function     * will cause the Java method to be called. The parameters of the method     * must be of number and types as defined by the FunctionObject class.     * The JavaScript function is then added as a property     * of the prototype. <p>     *     * If the method's name begins with "jsStaticFunction_", it is handled     * similarly except that the resulting JavaScript function is added as a     * property of the constructor object. The Java method must be static.     *     * If the method's name begins with "jsGet_" or "jsSet_", the method is     * considered to define a property. Accesses to the defined property     * will result in calls to these getter and setter methods. If no     * setter is defined, the property is defined as READONLY.<p>     *     * If the method's name is "jsConstructor", the method is     * considered to define the body of the constructor. Only one     * method of this name may be defined.     * If no method is found that can serve as constructor, a Java     * constructor will be selected to serve as the JavaScript     * constructor in the following manner. If the class has only one     * Java constructor, that constructor is used to define     * the JavaScript constructor. If the the class has two constructors,     * one must be the zero-argument constructor (otherwise an     * {@link EvaluatorException} would have already been thrown     * when the prototype was to be created). In this case     * the Java constructor with one or more parameters will be used     * to define the JavaScript constructor. If the class has three     * or more constructors, an {@link EvaluatorException}     * will be thrown.<p>     *     * Finally, if there is a method     * <pre>     * static void finishInit(Scriptable scope, FunctionObject constructor,     *                        Scriptable prototype)</pre>     *     * it will be called to finish any initialization. The <code>scope</code>     * argument will be passed, along with the newly created constructor and     * the newly created prototype.<p>     *     * @param scope The scope in which to define the constructor.     * @param clazz The Java class to use to define the JavaScript objects     *              and properties.     * @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     * @see org.mozilla.javascript.Function     * @see org.mozilla.javascript.FunctionObject     * @see org.mozilla.javascript.ScriptableObject#READONLY     * @see org.mozilla.javascript.ScriptableObject     *      #defineProperty(String, Class, int)     */    public static void defineClass(Scriptable scope, Class clazz)        throws IllegalAccessException, InstantiationException,               InvocationTargetException    {        defineClass(scope, clazz, false, false);    }    /**     * Defines JavaScript objects from a Java class, optionally     * allowing sealing.     *     * Similar to <code>defineClass(Scriptable scope, Class clazz)</code>     * except that sealing is 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.     * @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.4R3     */    public static void defineClass(Scriptable scope, Class clazz,                                   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 <code>defineClass(Scriptable scope, Class clazz)</code>     * 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    {        BaseFunction ctor = buildClassCtor(scope, clazz, sealed,                                           mapInheritance);        if (ctor == null)            return null;        String name = ctor.getClassPrototype().getClassName();        defineProperty(scope, name, ctor, ScriptableObject.DONTENUM);        return name;    }    static BaseFunction buildClassCtor(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++) {            Method method = methods[i];            if (!method.getName().equals("init"))                continue;            Class[] parmTypes = method.getParameterTypes();            if (parmTypes.length == 3 &&                parmTypes[0] == ScriptRuntime.ContextClass &&                parmTypes[1] == ScriptRuntime.ScriptableClass &&                parmTypes[2] == Boolean.TYPE &&                Modifier.isStatic(method.getModifiers()))            {                Object args[] = { Context.getContext(), scope,                                  sealed ? Boolean.TRUE : Boolean.FALSE };                method.invoke(null, args);                return null;            }            if (parmTypes.length == 1 &&                parmTypes[0] == ScriptRuntime.ScriptableClass &&                Modifier.isStatic(method.getModifiers()))            {                Object args[] = { scope };                method.invoke(null, args);                return null;            }        }        // If we got here, there isn't an "init" method with the right        // parameter types.        Constructor[] ctors = clazz.getConstructors();        Constructor protoCtor = null;        for (int i=0; i < ctors.length; i++) {            if (ctors[i].getParameterTypes().length == 0) {                protoCtor = ctors[i];                break;            }        }        if (protoCtor == null) {            throw Context.reportRuntimeError1(

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -