public static Class<?> generateClassImpl(String name, Modifiers modifiers, Class<?>[] interfaces, Class<?> superClass, BSHBlock block, Type type, CallStack callstack, Interpreter interpreter) throws EvalError {
        NameSpace enclosingNameSpace = callstack.top();
        String packageName = enclosingNameSpace.getPackage();
        String className = enclosingNameSpace.isClass ? (enclosingNameSpace.getName() + "$" + name) : name;
        String fqClassName = packageName == null ? className : packageName + "." + className;
        BshClassManager bcm = interpreter.getClassManager();
        // Race condition here...
        bcm.definingClass(fqClassName);

        // Create the class static namespace
        NameSpace classStaticNameSpace = new NameSpace(enclosingNameSpace, className);
        classStaticNameSpace.isClass = true;

        callstack.push(classStaticNameSpace);

        // Evaluate any inner class class definitions in the block
        // effectively recursively call this method for contained classes first
        block.evalBlock(callstack, interpreter, true/*override*/, ClassNodeFilter.CLASSCLASSES);

        // Generate the type for our class
        Variable[] variables = getDeclaredVariables(block, callstack, interpreter, packageName);
        DelayedEvalBshMethod[] methods = getDeclaredMethods(block, callstack, interpreter, packageName, superClass);

        callstack.pop();

        // initialize static this singleton in namespace
        classStaticNameSpace.getThis(interpreter);

        // Create the class generator, which encapsulates all knowledge of the
        // structure of the class
        ClassGeneratorUtil classGenerator = new ClassGeneratorUtil(modifiers, className, packageName, superClass, interfaces, variables, methods, classStaticNameSpace, type);

        // Let the class generator install hooks relating to the structure of
        // the class into the class static namespace.  e.g. the constructor
        // array.  This is necessary whether we are generating code or just
        // reinitializing a previously generated class.
        classGenerator.initStaticNameSpace(classStaticNameSpace, block/*instance initializer*/);

        // Check for existing class (saved class file)
        Class<?> genClass = bcm.getAssociatedClass(fqClassName);

        // If the class isn't there then generate it.
        // Else just let it be initialized below.
        if (genClass == null) {
            // generate bytecode, optionally with static init hooks to
            // bootstrap the interpreter
            byte[] code = classGenerator.generateClass();

            if (Interpreter.getSaveClasses())
                saveClasses(className, code);

            // Define the new class in the classloader
            genClass = bcm.defineClass(fqClassName, code);
            Interpreter.debug("Define ", fqClassName, " as ", genClass);
        }
        // import the unqualified class name into parent namespace
        enclosingNameSpace.importClass(fqClassName.replace('$', '.'));

        // Give the static space its class static import
        // important to do this after all classes are defined
        classStaticNameSpace.setClassStatic(genClass);

        Interpreter.debug(classStaticNameSpace);

        bcm.doneDefiningClass(fqClassName);

        if (interpreter.getStrictJava())
            ClassGeneratorUtil.checkAbstractMethodImplementation(genClass);

        return genClass;
    }
public static Class < ? > generateClassImpl ( String name , Modifiers modifiers , Class < ? > [ ] interfaces , Class < ? > superClass , BSHBlock block , Type type , CallStack callstack , Interpreter interpreter ) throws EvalError { NameSpace enclosingNameSpace = callstack . top ( ) ; String packageName = enclosingNameSpace . getPackage ( ) ; String className = enclosingNameSpace . isClass ? ( enclosingNameSpace . getName ( ) + "$" + name ) : name ; String fqClassName = packageName == null ? className : packageName + "." + className ; BshClassManager bcm = interpreter . getClassManager ( ) ; bcm . definingClass ( fqClassName ) ; NameSpace classStaticNameSpace = new NameSpace ( enclosingNameSpace , className ) ; classStaticNameSpace . isClass = true ; callstack . push ( classStaticNameSpace ) ; block . evalBlock ( callstack , interpreter , true , ClassNodeFilter . CLASSCLASSES ) ; Variable [ ] variables = getDeclaredVariables ( block , callstack , interpreter , packageName ) ; DelayedEvalBshMethod [ ] methods = getDeclaredMethods ( block , callstack , interpreter , packageName , superClass ) ; callstack . pop ( ) ; classStaticNameSpace . getThis ( interpreter ) ; ClassGeneratorUtil classGenerator = new ClassGeneratorUtil ( modifiers , className , packageName , superClass , interfaces , variables , methods , classStaticNameSpace , type ) ; classGenerator . initStaticNameSpace ( classStaticNameSpace , block ) ; Class < ? > genClass = bcm . getAssociatedClass ( fqClassName ) ; if ( genClass == null ) { byte [ ] code = classGenerator . generateClass ( ) ; if ( Interpreter . getSaveClasses ( ) ) saveClasses ( className , code ) ; genClass = bcm . defineClass ( fqClassName , code ) ; Interpreter . debug ( "Define " , fqClassName , " as " , genClass ) ; } enclosingNameSpace . importClass ( fqClassName . replace ( '$' , '.' ) ) ; classStaticNameSpace . setClassStatic ( genClass ) ; Interpreter . debug ( classStaticNameSpace ) ; bcm . doneDefiningClass ( fqClassName ) ; if ( interpreter . getStrictJava ( ) ) ClassGeneratorUtil . checkAbstractMethodImplementation ( genClass ) ; return genClass ; }
Parse the BSHBlock for for the class definition and generate the class
using ClassGenerator.