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; } if (parmTypes.length == 1 && parmTypes[0] == ScriptRuntime.ScriptableClass && Modifier.isStatic(method.getModifiers())) { Object args[] = { scope }; method.invoke(null, args); return; }  }     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 new ClassDefinitionException( Context.getMessage1("msg.zero.arg.ctor", clazz.getName())); }  Scriptable proto = (Scriptable) protoCtor.newInstance(ScriptRuntime.emptyArgs); proto.setPrototype(getObjectPrototype(scope)); String className = proto.getClassName();     final String functionPrefix = "jsFunction_"; final String staticFunctionPrefix = "jsStaticFunction_"; final String getterPrefix = "jsGet_"; final String setterPrefix = "jsSet_"; final String ctorName = "jsConstructor";  Member ctorMember = FunctionObject.findSingleMethod(methods, ctorName);  if (ctorMember == null) { if (ctors.length == 1) { ctorMember = ctors[0]; } else if (ctors.length == 2) { if (ctors[0].getParameterTypes().length == 0) ctorMember = ctors[1]; else if (ctors[1].getParameterTypes().length == 0) ctorMember = ctors[0]; } if (ctorMember == null) { throw new ClassDefinitionException( Context.getMessage1("msg.ctor.multiple.parms", clazz.getName())); } }  FunctionObject ctor = new FunctionObject(className, ctorMember, scope); if (ctor.isVarArgsMethod()) { throw Context.reportRuntimeError1 ("msg.varargs.ctor", ctorMember.getName()); } ctor.addAsConstructor(scope, proto);  Method finishInit = null; for (int i=0; i < methods.length; i++) { if (methods[i] == ctorMember) { continue; } String name = methods[i].getName(); if (name.equals("finishInit")) { Class[] parmTypes = methods[i].getParameterTypes(); if (parmTypes.length == 3 && parmTypes[0] == ScriptRuntime.ScriptableClass && parmTypes[1] == FunctionObject.class && parmTypes[2] == ScriptRuntime.ScriptableClass && Modifier.isStatic(methods[i].getModifiers())) { finishInit = methods[i]; continue; } }  if (name.indexOf('$') != -1) continue; if (name.equals(ctorName)) continue;  String prefix = null; if (name.startsWith(functionPrefix)) { prefix = functionPrefix; } else if (name.startsWith(staticFunctionPrefix)) { prefix = staticFunctionPrefix; if (!Modifier.isStatic(methods[i].getModifiers())) { throw new ClassDefinitionException( "jsStaticFunction must be used with static method."); } } else if (name.startsWith(getterPrefix)) { prefix = getterPrefix; } else if (name.startsWith(setterPrefix)) { prefix = setterPrefix; } else { continue; } name = name.substring(prefix.length()); if (prefix == setterPrefix) continue; if (prefix == getterPrefix) { if (!(proto instanceof ScriptableObject)) { throw PropertyException.withMessage2 ("msg.extend.scriptable",                                                         proto.getClass().toString(), name); } Method setter = FunctionObject.findSingleMethod( methods, setterPrefix + name); int attr = ScriptableObject.PERMANENT | ScriptableObject.DONTENUM  | (setter != null ? 0 : ScriptableObject.READONLY); ((ScriptableObject) proto).defineProperty(name, null, methods[i], setter, attr); continue; }  FunctionObject f = new FunctionObject(name, methods[i], proto); if (f.isVarArgsConstructor()) { throw Context.reportRuntimeError1 ("msg.varargs.fun", ctorMember.getName()); } Scriptable dest = prefix == staticFunctionPrefix ? ctor : proto; defineProperty(dest, name, f, DONTENUM); if (sealed) { f.sealObject(); } }  if (finishInit != null) {  Object[] finishArgs = { scope, ctor, proto }; finishInit.invoke(null, finishArgs); }  if (sealed) { ctor.sealObject(); if (proto instanceof ScriptableObject) { ((ScriptableObject) proto).sealObject(); } }
defineClass(scope, clazz, false);
    public static void defineClass(Scriptable scope, Class clazz,                                   boolean sealed)        throws IllegalAccessException, InstantiationException,               InvocationTargetException, ClassDefinitionException,               PropertyException    {        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;            }            if (parmTypes.length == 1 &&                parmTypes[0] == ScriptRuntime.ScriptableClass &&                Modifier.isStatic(method.getModifiers()))            {                Object args[] = { scope };                method.invoke(null, args);                return;            }        }        // 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 new ClassDefinitionException(                    Context.getMessage1("msg.zero.arg.ctor", clazz.getName()));        }        Scriptable proto = (Scriptable)                        protoCtor.newInstance(ScriptRuntime.emptyArgs);        proto.setPrototype(getObjectPrototype(scope));        String className = proto.getClassName();        // 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.        final String functionPrefix = "jsFunction_";        final String staticFunctionPrefix = "jsStaticFunction_";        final String getterPrefix = "jsGet_";        final String setterPrefix = "jsSet_";        final String ctorName = "jsConstructor";        Member ctorMember = FunctionObject.findSingleMethod(methods, ctorName);        if (ctorMember == null) {            if (ctors.length == 1) {                ctorMember = ctors[0];            } else if (ctors.length == 2) {                if (ctors[0].getParameterTypes().length == 0)                    ctorMember = ctors[1];                else if (ctors[1].getParameterTypes().length == 0)                    ctorMember = ctors[0];            }            if (ctorMember == null) {                throw new ClassDefinitionException(                    Context.getMessage1("msg.ctor.multiple.parms",                                        clazz.getName()));            }        }        FunctionObject ctor = new FunctionObject(className, ctorMember, scope);        if (ctor.isVarArgsMethod()) {            throw Context.reportRuntimeError1                ("msg.varargs.ctor", ctorMember.getName());        }        ctor.addAsConstructor(scope, proto);        Method finishInit = null;        for (int i=0; i < methods.length; i++) {            if (methods[i] == ctorMember) {                continue;            }            String name = methods[i].getName();            if (name.equals("finishInit")) {                Class[] parmTypes = methods[i].getParameterTypes();                if (parmTypes.length == 3 &&                    parmTypes[0] == ScriptRuntime.ScriptableClass &&                    parmTypes[1] == FunctionObject.class &&                    parmTypes[2] == ScriptRuntime.ScriptableClass &&                    Modifier.isStatic(methods[i].getModifiers()))                {                    finishInit = methods[i];                    continue;                }            }            // ignore any compiler generated methods.            if (name.indexOf('$') != -1)                continue;            if (name.equals(ctorName))                continue;            String prefix = null;            if (name.startsWith(functionPrefix)) {                prefix = functionPrefix;            } else if (name.startsWith(staticFunctionPrefix)) {                prefix = staticFunctionPrefix;                if (!Modifier.isStatic(methods[i].getModifiers())) {                    throw new ClassDefinitionException(                        "jsStaticFunction must be used with static method.");                }            } else if (name.startsWith(getterPrefix)) {                prefix = getterPrefix;            } else if (name.startsWith(setterPrefix)) {                prefix = setterPrefix;            } else {                continue;            }            name = name.substring(prefix.length());            if (prefix == setterPrefix)                continue;   // deal with set when we see get            if (prefix == getterPrefix) {                if (!(proto instanceof ScriptableObject)) {                    throw PropertyException.withMessage2                        ("msg.extend.scriptable",                                                         proto.getClass().toString(), name);                }                Method setter = FunctionObject.findSingleMethod(                                    methods,                                    setterPrefix + name);                int attr = ScriptableObject.PERMANENT |                           ScriptableObject.DONTENUM  |                           (setter != null ? 0                                           : ScriptableObject.READONLY);                ((ScriptableObject) proto).defineProperty(name, null,                                                          methods[i], setter,                                                          attr);                continue;            }            FunctionObject f = new FunctionObject(name, methods[i], proto);            if (f.isVarArgsConstructor()) {                throw Context.reportRuntimeError1                    ("msg.varargs.fun", ctorMember.getName());            }            Scriptable dest = prefix == staticFunctionPrefix                              ? ctor                              : proto;            defineProperty(dest, name, f, DONTENUM);            if (sealed) {                f.sealObject();            }        }        if (finishInit != null) {            // call user code to complete the initialization            Object[] finishArgs = { scope, ctor, proto };            finishInit.invoke(null, finishArgs);        }        if (sealed) {            ctor.sealObject();            if (proto instanceof ScriptableObject) {                ((ScriptableObject) proto).sealObject();            }        }    }