📄 functionobject.java
字号:
Method method = methods[i]; if (method != null && name.equals(method.getName())) { if (found != null) { throw Context.reportRuntimeError2( "msg.no.overload", name, method.getDeclaringClass().getName()); } found = method; } } 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 { // getDeclaredMethods may be rejected by the security manager // but getMethods is more expensive if (!sawSecurityException) methods = clazz.getDeclaredMethods(); } catch (SecurityException e) { // If we get an exception once, give up on getDeclaredMethods sawSecurityException = true; } if (methods == null) { methods = clazz.getMethods(); } int count = 0; for (int i=0; i < methods.length; i++) { if (sawSecurityException ? methods[i].getDeclaringClass() != clazz : !Modifier.isPublic(methods[i].getModifiers())) { methods[i] = null; } else { count++; } } Method[] result = new Method[count]; int j=0; for (int i=0; i < methods.length; i++) { if (methods[i] != null) result[j++] = methods[i]; } return result; } /** * Define this function as a JavaScript constructor. * <p> * Sets up the "prototype" and "constructor" properties. Also * calls setParent and setPrototype with appropriate values. * Then adds the function object as a property of the given scope, using * <code>prototype.getClassName()</code> * as the name of the property. * * @param scope the scope in which to define the constructor (typically * the global object) * @param prototype the prototype object * @see org.mozilla.javascript.Scriptable#setParentScope * @see org.mozilla.javascript.Scriptable#setPrototype * @see org.mozilla.javascript.Scriptable#getClassName */ public void addAsConstructor(Scriptable scope, Scriptable prototype) { ScriptRuntime.setFunctionProtoAndParent(this, scope); setImmunePrototypeProperty(prototype); prototype.setParentScope(this); final int attr = ScriptableObject.DONTENUM | ScriptableObject.PERMANENT | ScriptableObject.READONLY; defineProperty(prototype, "constructor", this, attr); String name = prototype.getClassName(); defineProperty(scope, name, this, ScriptableObject.DONTENUM); setParentScope(scope); } /** * @deprecated Use {@link #getTypeTag(Class)} * and {@link #convertArg(Context, Scriptable, Object, int)} * for type convertion. */ public static Object convertArg(Context cx, Scriptable scope, Object arg, Class desired) { int tag = getTypeTag(desired); if (tag == JAVA_UNSUPPORTED_TYPE) { throw Context.reportRuntimeError1 ("msg.cant.convert", desired.getName()); } return convertArg(cx, scope, arg, tag); } /** * Performs conversions on argument types if needed and * invokes the underlying Java method or constructor. * <p> * Implements Function.call. * * @see org.mozilla.javascript.Function#call( * Context, Scriptable, Scriptable, Object[]) */ public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { Object result; boolean checkMethodResult = false; if (parmsLength < 0) { if (parmsLength == VARARGS_METHOD) { Object[] invokeArgs = { cx, thisObj, args, this }; result = member.invoke(null, invokeArgs); checkMethodResult = true; } else { boolean inNewExpr = (thisObj == null); Boolean b = inNewExpr ? Boolean.TRUE : Boolean.FALSE; Object[] invokeArgs = { cx, args, this, b }; result = (member.isCtor()) ? member.newInstance(invokeArgs) : member.invoke(null, invokeArgs); } } else { if (!isStatic) { Class clazz = member.getDeclaringClass(); if (!clazz.isInstance(thisObj)) { boolean compatible = false; if (thisObj == scope) { Scriptable parentScope = getParentScope(); if (scope != parentScope) { // Call with dynamic scope for standalone function, // use parentScope as thisObj compatible = clazz.isInstance(parentScope); if (compatible) { thisObj = parentScope; } } } if (!compatible) { // Couldn't find an object to call this on. throw ScriptRuntime.typeError1("msg.incompat.call", functionName); } } } Object[] invokeArgs; if (parmsLength == args.length) { // Do not allocate new argument array if java arguments are // the same as the original js ones. invokeArgs = args; for (int i = 0; i != parmsLength; ++i) { Object arg = args[i]; Object converted = convertArg(cx, scope, arg, typeTags[i]); if (arg != converted) { if (invokeArgs == args) { invokeArgs = (Object[])args.clone(); } invokeArgs[i] = converted; } } } else if (parmsLength == 0) { invokeArgs = ScriptRuntime.emptyArgs; } else { invokeArgs = new Object[parmsLength]; for (int i = 0; i != parmsLength; ++i) { Object arg = (i < args.length) ? args[i] : Undefined.instance; invokeArgs[i] = convertArg(cx, scope, arg, typeTags[i]); } } if (member.isMethod()) { result = member.invoke(thisObj, invokeArgs); checkMethodResult = true; } else { result = member.newInstance(invokeArgs); } } if (checkMethodResult) { if (hasVoidReturn) { result = Undefined.instance; } else if (returnTypeTag == JAVA_UNSUPPORTED_TYPE) { result = cx.getWrapFactory().wrap(cx, scope, result, null); } // XXX: the code assumes that if returnTypeTag == JAVA_OBJECT_TYPE // then the Java method did a proper job of converting the // result to JS primitive or Scriptable to avoid // potentially costly Context.javaToJS call. } return result; } /** * Return new {@link Scriptable} instance using the default * constructor for the class of the underlying Java method. * Return null to indicate that the call method should be used to create * new objects. */ public Scriptable createObject(Context cx, Scriptable scope) { if (member.isCtor() || parmsLength == VARARGS_CTOR) { return null; } Scriptable result; try { result = (Scriptable) member.getDeclaringClass().newInstance(); } catch (Exception ex) { throw Context.throwAsScriptRuntimeEx(ex); } result.setPrototype(getClassPrototype()); result.setParentScope(getParentScope()); return result; } boolean isVarArgsMethod() { return parmsLength == VARARGS_METHOD; } boolean isVarArgsConstructor() { return parmsLength == VARARGS_CTOR; } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); if (parmsLength > 0) { Class[] types = member.argTypes; typeTags = new byte[parmsLength]; for (int i = 0; i != parmsLength; ++i) { typeTags[i] = (byte)getTypeTag(types[i]); } } if (member.isMethod()) { Method method = member.method(); Class returnType = method.getReturnType(); if (returnType == Void.TYPE) { hasVoidReturn = true; } else { returnTypeTag = getTypeTag(returnType); } } } private static final short VARARGS_METHOD = -1; private static final short VARARGS_CTOR = -2; private static boolean sawSecurityException; public static final int JAVA_UNSUPPORTED_TYPE = 0; public static final int JAVA_STRING_TYPE = 1; public static final int JAVA_INT_TYPE = 2; public static final int JAVA_BOOLEAN_TYPE = 3; public static final int JAVA_DOUBLE_TYPE = 4; public static final int JAVA_SCRIPTABLE_TYPE = 5; public static final int JAVA_OBJECT_TYPE = 6; MemberBox member; private String functionName; private transient byte[] typeTags; private int parmsLength; private transient boolean hasVoidReturn; private transient int returnTypeTag; private boolean isStatic;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -