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

📄 functionobject.java

📁 java中比较著名的js引擎当属mozilla开源的rhino
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): *   Norris Boyd *   Igor Bukanov *   David C. Navas *   Ted Neward * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */// API classpackage org.mozilla.javascript;import java.lang.reflect.*;import java.io.*;public class FunctionObject extends BaseFunction{    static final long serialVersionUID = -5332312783643935019L;    /**     * Create a JavaScript function object from a Java method.     *     * <p>The <code>member</code> argument must be either a java.lang.reflect.Method     * or a java.lang.reflect.Constructor and must match one of two forms.<p>     *     * The first form is a member with zero or more parameters     * of the following types: Object, String, boolean, Scriptable,     * int, or double. The Long type is not supported     * because the double representation of a long (which is the     * EMCA-mandated storage type for Numbers) may lose precision.     * If the member is a Method, the return value must be void or one     * of the types allowed for parameters.<p>     *     * The runtime will perform appropriate conversions based     * upon the type of the parameter. A parameter type of     * Object specifies that no conversions are to be done. A parameter     * of type String will use Context.toString to convert arguments.     * Similarly, parameters of type double, boolean, and Scriptable     * will cause Context.toNumber, Context.toBoolean, and     * Context.toObject, respectively, to be called.<p>     *     * If the method is not static, the Java 'this' value will     * correspond to the JavaScript 'this' value. Any attempt     * to call the function with a 'this' value that is not     * of the right Java type will result in an error.<p>     *     * The second form is the variable arguments (or "varargs")     * form. If the FunctionObject will be used as a constructor,     * the member must have the following parameters     * <pre>     *      (Context cx, Object[] args, Function ctorObj,     *       boolean inNewExpr)</pre>     * and if it is a Method, be static and return an Object result.<p>     *     * Otherwise, if the FunctionObject will <i>not</i> be used to define a     * constructor, the member must be a static Method with parameters     *      (Context cx, Scriptable thisObj, Object[] args,     *       Function funObj) </pre>     * <pre>     * and an Object result.<p>     *     * When the function varargs form is called as part of a function call,     * the <code>args</code> parameter contains the     * arguments, with <code>thisObj</code>     * set to the JavaScript 'this' value. <code>funObj</code>     * is the function object for the invoked function.<p>     *     * When the constructor varargs form is called or invoked while evaluating     * a <code>new</code> expression, <code>args</code> contains the     * arguments, <code>ctorObj</code> refers to this FunctionObject, and     * <code>inNewExpr</code> is true if and only if  a <code>new</code>     * expression caused the call. This supports defining a function that     * has different behavior when called as a constructor than when     * invoked as a normal function call. (For example, the Boolean     * constructor, when called as a function,     * will convert to boolean rather than creating a new object.)<p>     *     * @param name the name of the function     * @param methodOrConstructor a java.lang.reflect.Method or a java.lang.reflect.Constructor     *                            that defines the object     * @param scope enclosing scope of function     * @see org.mozilla.javascript.Scriptable     */    public FunctionObject(String name, Member methodOrConstructor,                          Scriptable scope)    {        if (methodOrConstructor instanceof Constructor) {            member = new MemberBox((Constructor) methodOrConstructor);            isStatic = true; // well, doesn't take a 'this'        } else {            member = new MemberBox((Method) methodOrConstructor);            isStatic = member.isStatic();        }        String methodName = member.getName();        this.functionName = name;        Class[] types = member.argTypes;        int arity = types.length;        if (arity == 4 && (types[1].isArray() || types[2].isArray())) {            // Either variable args or an error.            if (types[1].isArray()) {                if (!isStatic ||                    types[0] != ScriptRuntime.ContextClass ||                    types[1].getComponentType() != ScriptRuntime.ObjectClass ||                    types[2] != ScriptRuntime.FunctionClass ||                    types[3] != Boolean.TYPE)                {                    throw Context.reportRuntimeError1(                        "msg.varargs.ctor", methodName);                }                parmsLength = VARARGS_CTOR;            } else {                if (!isStatic ||                    types[0] != ScriptRuntime.ContextClass ||                    types[1] != ScriptRuntime.ScriptableClass ||                    types[2].getComponentType() != ScriptRuntime.ObjectClass ||                    types[3] != ScriptRuntime.FunctionClass)                {                    throw Context.reportRuntimeError1(                        "msg.varargs.fun", methodName);                }                parmsLength = VARARGS_METHOD;            }        } else {            parmsLength = arity;            if (arity > 0) {                typeTags = new byte[arity];                for (int i = 0; i != arity; ++i) {                    int tag = getTypeTag(types[i]);                    if (tag == JAVA_UNSUPPORTED_TYPE) {                        throw Context.reportRuntimeError2(                            "msg.bad.parms", types[i].getName(), methodName);                    }                    typeTags[i] = (byte)tag;                }            }        }        if (member.isMethod()) {            Method method = member.method();            Class returnType = method.getReturnType();            if (returnType == Void.TYPE) {                hasVoidReturn = true;            } else {                returnTypeTag = getTypeTag(returnType);            }        } else {            Class ctorType = member.getDeclaringClass();            if (!ScriptRuntime.ScriptableClass.isAssignableFrom(ctorType)) {                throw Context.reportRuntimeError1(                    "msg.bad.ctor.return", ctorType.getName());            }        }        ScriptRuntime.setFunctionProtoAndParent(this, scope);    }    /**     * @return One of <tt>JAVA_*_TYPE</tt> constants to indicate desired type     *         or {@link #JAVA_UNSUPPORTED_TYPE} if the convertion is not     *         possible     */    public static int getTypeTag(Class type)    {        if (type == ScriptRuntime.StringClass)            return JAVA_STRING_TYPE;        if (type == ScriptRuntime.IntegerClass || type == Integer.TYPE)            return JAVA_INT_TYPE;        if (type == ScriptRuntime.BooleanClass || type == Boolean.TYPE)            return JAVA_BOOLEAN_TYPE;        if (type == ScriptRuntime.DoubleClass || type == Double.TYPE)            return JAVA_DOUBLE_TYPE;        if (ScriptRuntime.ScriptableClass.isAssignableFrom(type))            return JAVA_SCRIPTABLE_TYPE;        if (type == ScriptRuntime.ObjectClass)            return JAVA_OBJECT_TYPE;        // Note that the long type is not supported; see the javadoc for        // the constructor for this class        return JAVA_UNSUPPORTED_TYPE;    }    public static Object convertArg(Context cx, Scriptable scope,                                    Object arg, int typeTag)    {        switch (typeTag) {          case JAVA_STRING_TYPE:              if (arg instanceof String)                return arg;            return ScriptRuntime.toString(arg);          case JAVA_INT_TYPE:              if (arg instanceof Integer)                return arg;            return new Integer(ScriptRuntime.toInt32(arg));          case JAVA_BOOLEAN_TYPE:              if (arg instanceof Boolean)                return arg;            return ScriptRuntime.toBoolean(arg) ? Boolean.TRUE                                                : Boolean.FALSE;          case JAVA_DOUBLE_TYPE:            if (arg instanceof Double)                return arg;            return new Double(ScriptRuntime.toNumber(arg));          case JAVA_SCRIPTABLE_TYPE:            if (arg instanceof Scriptable)                return arg;            return ScriptRuntime.toObject(cx, scope, arg);          case JAVA_OBJECT_TYPE:            return arg;          default:            throw new IllegalArgumentException();        }    }    /**     * Return the value defined by  the method used to construct the object     * (number of parameters of the method, or 1 if the method is a "varargs"     * form).     */    public int getArity() {        return parmsLength < 0 ? 1 : parmsLength;    }    /**     * Return the same value as {@link #getArity()}.     */    public int getLength() {        return getArity();    }    public String getFunctionName()    {        return (functionName == null) ? "" : functionName;    }    /**     * Get Java method or constructor this function represent.     */    public Member getMethodOrConstructor()    {        if (member.isMethod()) {            return member.method();        } else {            return member.ctor();        }    }    static Method findSingleMethod(Method[] methods, String name)    {        Method found = null;        for (int i = 0, N = methods.length; i != N; ++i) {

⌨️ 快捷键说明

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