Example usage for org.objectweb.asm Opcodes ACC_FINAL

List of usage examples for org.objectweb.asm Opcodes ACC_FINAL

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes ACC_FINAL.

Prototype

int ACC_FINAL

To view the source code for org.objectweb.asm Opcodes ACC_FINAL.

Click Source Link

Usage

From source file:org.codehaus.groovy.eclipse.codeassist.creators.FieldProposalCreator.java

License:Apache License

private static GroovyFieldProposal createClassProposal() {
    FieldNode field = new FieldNode("class", Opcodes.ACC_PUBLIC & Opcodes.ACC_STATIC & Opcodes.ACC_FINAL,
            VariableScope.CLASS_CLASS_NODE, VariableScope.OBJECT_CLASS_NODE, null);
    field.setDeclaringClass(VariableScope.OBJECT_CLASS_NODE);
    return new GroovyFieldProposal(field);
}

From source file:org.codehaus.groovy.eclipse.codeassist.processors.NewMethodCompletionProcessor.java

License:Apache License

/**
 * @param allMethodNode/*from  w w  w . j  av a 2  s. co m*/
 * @return
 */
private boolean isOverridableMethod(MethodNode methodNode) {
    String name = methodNode.getName();
    return !name.contains("$") && !name.contains("<") && !methodNode.isPrivate() && !methodNode.isStatic()
            && (methodNode.getModifiers() & Opcodes.ACC_FINAL) == 0;
}

From source file:org.codehaus.groovy.parser.antlr4.ASTBuilder.java

License:Apache License

public ClassNode parseClassDeclaration(final GroovyLangParser.ClassDeclarationContext ctx) {
    boolean isEnum = asBoolean(ctx.KW_ENUM());

    final ClassNode outerClass = asBoolean(classNodeStack) ? classNodeStack.peek() : null;
    ClassNode[] interfaces = asBoolean(ctx.implementsClause())
            ? collect(ctx.implementsClause().genericClassNameExpression(), new Closure<ClassNode>(this, this) {
                public ClassNode doCall(GroovyLangParser.GenericClassNameExpressionContext it) {
                    return parseExpression(it);
                }//ww w .j  a v  a  2  s . c o m
            }).toArray(new ClassNode[0])
            : new ClassNode[0];

    ClassNode classNode;
    String packageName = moduleNode.getPackageName();
    packageName = packageName != null && asBoolean(packageName) ? packageName : "";

    if (isEnum) {
        classNode = EnumHelper.makeEnumNode(
                asBoolean(outerClass) ? ctx.IDENTIFIER().getText() : packageName + ctx.IDENTIFIER().getText(),
                Modifier.PUBLIC, interfaces, outerClass);
    } else {
        if (outerClass != null) {
            String name = outerClass.getName() + "$" + String.valueOf(ctx.IDENTIFIER());
            classNode = new InnerClassNode(outerClass, name, Modifier.PUBLIC, ClassHelper.OBJECT_TYPE);
        } else {
            classNode = new ClassNode(packageName + String.valueOf(ctx.IDENTIFIER()), Modifier.PUBLIC,
                    ClassHelper.OBJECT_TYPE);
        }
    }

    setupNodeLocation(classNode, ctx);

    if (asBoolean(ctx.KW_TRAIT())) {
        attachTraitTransformAnnotation(classNode);
    }

    attachAnnotations(classNode, ctx.annotationClause());

    //        moduleNode.addClass(classNode);
    classes.add(classNode);
    if (asBoolean(ctx.extendsClause())) {
        if (asBoolean(ctx.KW_INTERFACE()) && !asBoolean(ctx.AT())) { // interface(NOT annotation)
            List<ClassNode> interfaceList = new LinkedList<ClassNode>();
            for (GroovyLangParser.GenericClassNameExpressionContext genericClassNameExpressionContext : ctx
                    .extendsClause().genericClassNameExpression()) {
                interfaceList.add(parseExpression(genericClassNameExpressionContext));
            }
            (classNode).setInterfaces(interfaceList.toArray(new ClassNode[0]));
            (classNode).setSuperClass(ClassHelper.OBJECT_TYPE);
        } else {
            (classNode).setSuperClass(parseExpression(ctx.extendsClause().genericClassNameExpression(0)));
        }

    }

    if (asBoolean(ctx.implementsClause())) {
        (classNode).setInterfaces(interfaces);
    }

    if (!isEnum) {
        (classNode).setGenericsTypes(parseGenericDeclaration(ctx.genericDeclarationList()));
        (classNode).setUsingGenerics(
                (classNode.getGenericsTypes() != null && classNode.getGenericsTypes().length != 0)
                        || (classNode).getSuperClass().isUsingGenerics() || DefaultGroovyMethods
                                .any(classNode.getInterfaces(), new Closure<Boolean>(this, this) {
                                    public Boolean doCall(ClassNode it) {
                                        return it.isUsingGenerics();
                                    }
                                }));
    }

    classNode.setModifiers(
            parseClassModifiers(ctx.classModifier()) | (isEnum ? (Opcodes.ACC_ENUM | Opcodes.ACC_FINAL)
                    : ((asBoolean(ctx.KW_INTERFACE()) ? Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT : 0))));

    classNode.setSyntheticPublic((classNode.getModifiers() & Opcodes.ACC_SYNTHETIC) != 0);
    classNode.setModifiers(classNode.getModifiers() & ~Opcodes.ACC_SYNTHETIC);// FIXME Magic with synthetic modifier.

    if (asBoolean(ctx.AT())) {
        classNode.addInterface(ClassHelper.Annotation_TYPE);
        classNode.setModifiers(classNode.getModifiers() | Opcodes.ACC_ANNOTATION);
    }

    classNodeStack.add(classNode);
    parseClassBody(classNode, ctx.classBody());
    classNodeStack.pop();

    if (classNode.isInterface()) { // FIXME why interface has null mixin
        try {
            // FIXME Hack with visibility.
            Field field = ClassNode.class.getDeclaredField("mixins");
            field.setAccessible(true);
            field.set(classNode, null);
        } catch (IllegalAccessException e) {
            log.warning(createExceptionMessage(e));
        } catch (NoSuchFieldException e) {
            log.warning(createExceptionMessage(e));
        }
    }

    this.attachDocCommentAsMetaData(classNode, ctx);

    return classNode;
}

From source file:org.codehaus.groovy.parser.antlr4.ASTBuilder.java

License:Apache License

public AnnotatedNode parseMember(ClassNode classNode, GroovyLangParser.FieldDeclarationContext ctx) {
    //noinspection GroovyAssignabilityCheck
    final Iterator<Object> iterator = parseModifiers(ctx.memberModifier()).iterator();
    int modifiers = ((Integer) (iterator.hasNext() ? iterator.next() : null));
    boolean hasVisibilityModifier = ((Boolean) (iterator.hasNext() ? iterator.next() : null));

    modifiers |= classNode.isInterface() ? Opcodes.ACC_STATIC | Opcodes.ACC_FINAL : 0;

    AnnotatedNode node = null;//from  ww w . java  2s  .co  m
    List<? extends GroovyLangParser.SingleDeclarationContext> variables = ctx.singleDeclaration();
    for (GroovyLangParser.SingleDeclarationContext variableCtx : variables) {
        GroovyLangParser.ExpressionContext initExprContext = variableCtx.expression();
        Expression initialierExpression = asBoolean(initExprContext) ? parseExpression(initExprContext) : null;
        ClassNode typeDeclaration = asBoolean(ctx.genericClassNameExpression())
                ? parseExpression(ctx.genericClassNameExpression())
                : ClassHelper.OBJECT_TYPE;

        Object defaultValue = findDefaultValueByType(typeDeclaration);
        Expression initialValue = classNode.isInterface() && (null == initialierExpression)
                ? (null == defaultValue ? null : new ConstantExpression(defaultValue))
                : initialierExpression;

        org.codehaus.groovy.syntax.Token token;
        if (asBoolean(variableCtx.ASSIGN())) {
            token = createGroovyToken(variableCtx.ASSIGN().getSymbol(), Types.ASSIGN);
        } else {
            int line = variableCtx.start.getLine();
            int col = -1; //ASSIGN TOKEN DOES NOT APPEAR, SO COL IS -1. IF NO ERROR OCCURS, THE ORIGINAL CODE CAN BE REMOVED IN THE FURTURE: variableCtx.getStart().getCharPositionInLine() + 1; // FIXME Why assignment token location is it's first occurrence.

            token = new org.codehaus.groovy.syntax.Token(Types.ASSIGN, "=", line, col);
        }

        if (classNode.isInterface() || hasVisibilityModifier) {
            modifiers |= classNode.isInterface() ? Opcodes.ACC_PUBLIC : 0;

            FieldNode field = classNode.addField(variableCtx.IDENTIFIER().getText(), modifiers, typeDeclaration,
                    initialValue, token);
            attachAnnotations(field, ctx.annotationClause());
            node = setupNodeLocation(field, variables.size() == 1 ? ctx : variableCtx);
        } else {// no visibility specified. Generate property node.
            Integer propertyModifier = modifiers | Opcodes.ACC_PUBLIC;
            PropertyNode propertyNode = classNode.addProperty(variableCtx.IDENTIFIER().getText(),
                    propertyModifier, typeDeclaration, initialValue, null, null, token);
            propertyNode.getField().setModifiers(modifiers | Opcodes.ACC_PRIVATE);
            propertyNode.getField().setSynthetic(!classNode.isInterface());
            node = setupNodeLocation(propertyNode.getField(), variables.size() == 1 ? ctx : variableCtx);
            attachAnnotations(propertyNode.getField(), ctx.annotationClause());
            setupNodeLocation(propertyNode, variables.size() == 1 ? ctx : variableCtx);
        }
    }
    return node;
}

From source file:org.codehaus.groovy.parser.antlr4.ASTBuilder.java

License:Apache License

public List<DeclarationExpression> parseDeclaration(GroovyLangParser.DeclarationRuleContext ctx) {
    List<DeclarationExpression> declarations = new LinkedList<DeclarationExpression>();

    if (asBoolean(ctx.tupleDeclaration())) {
        DeclarationExpression declarationExpression = parseTupleDeclaration(ctx.tupleDeclaration(),
                asBoolean(ctx.KW_FINAL()));

        declarations.add(declarationExpression);

        return declarations;
    }//from  w w  w  . jav a  2 s  . c o m

    ClassNode nullClassNode = new ClassNode("", Modifier.PUBLIC, ClassHelper.OBJECT_TYPE);
    AnnotatedNode node = this.parseMember(nullClassNode, ctx.fieldDeclaration());

    for (PropertyNode propertyNode : nullClassNode.getProperties()) {
        VariableExpression left = new VariableExpression(propertyNode.getName(), propertyNode.getType());
        left.setModifiers(propertyNode.getModifiers() & Opcodes.ACC_FINAL);

        Expression initialValue = propertyNode.getInitialExpression();
        initialValue = initialValue != null ? initialValue : setupNodeLocation(new EmptyExpression(), ctx);

        DeclarationExpression expression = new DeclarationExpression(left, propertyNode.getAssignToken(),
                initialValue);
        expression.addAnnotations(propertyNode.getField().getAnnotations());

        declarations.add(setupNodeLocation(expression, propertyNode));
    }

    int declarationsSize = declarations.size();
    if (declarationsSize == 1) {
        setupNodeLocation(declarations.get(0), ctx);
    } else if (declarationsSize > 0) {
        DeclarationExpression declarationExpression = declarations.get(0);
        // Tweak start of first declaration
        declarationExpression.setLineNumber(ctx.getStart().getLine());
        declarationExpression.setColumnNumber(ctx.getStart().getCharPositionInLine() + 1);
    }

    return declarations;
}

From source file:org.codehaus.groovy.parser.antlr4.ASTBuilder.java

License:Apache License

public DeclarationExpression parseTupleDeclaration(GroovyLangParser.TupleDeclarationContext ctx,
        boolean isFinal) {
    // tuple must have an initial value.
    if (null == ctx.expression()) {
        throw createParsingFailedException(
                new InvalidSyntaxException("tuple declaration must have an initial value.", ctx));
    }//from  ww w  .j  a va  2 s  .  c  om

    List<Expression> variables = new LinkedList<Expression>();

    for (GroovyLangParser.TupleVariableDeclarationContext tupleVariableDeclarationContext : ctx
            .tupleVariableDeclaration()) {
        VariableExpression variableExpression = parseTupleVariableDeclaration(tupleVariableDeclarationContext);

        if (isFinal) {
            variableExpression.setModifiers(Opcodes.ACC_FINAL);
        }

        variables.add(variableExpression);
    }

    ArgumentListExpression argumentListExpression = new ArgumentListExpression(variables);
    org.codehaus.groovy.syntax.Token token = createGroovyToken(ctx.ASSIGN().getSymbol(), Types.ASSIGN);

    Expression initialValue = (ctx != null) ? parseExpression(ctx.expression())
            : setupNodeLocation(new EmptyExpression(), ctx);

    DeclarationExpression declarationExpression = new DeclarationExpression(argumentListExpression, token,
            initialValue);

    return setupNodeLocation(declarationExpression, ctx);
}

From source file:org.codehaus.groovy.parser.antlr4.ASTBuilder.java

License:Apache License

public Parameter[] parseParameters(GroovyLangParser.ArgumentDeclarationListContext ctx) {
    List<Parameter> parameterList = ctx == null || ctx.argumentDeclaration() == null
            ? new LinkedList<Parameter>()
            : collect(ctx.argumentDeclaration(), new Closure<Parameter>(null, null) {
                public Parameter doCall(GroovyLangParser.ArgumentDeclarationContext it) {
                    Parameter parameter = new Parameter(parseTypeDeclaration(it.typeDeclaration()),
                            it.IDENTIFIER().getText());
                    attachAnnotations(parameter, it.annotationClause());

                    if (asBoolean(it.KW_FINAL())) {
                        parameter.setModifiers(Opcodes.ACC_FINAL);
                    }// w  w w . j av a  2 s  . c  o m

                    if (asBoolean(it.expression()))
                        parameter.setInitialExpression(parseExpression(it.expression()));

                    return setupNodeLocation(parameter, it);
                }
            });
    return parameterList.toArray(new Parameter[parameterList.size()]);
}

From source file:org.codehaus.groovy.parser.antlr4.ASTBuilder.java

License:Apache License

public int parseClassModifiers(List<? extends GroovyLangParser.ClassModifierContext> ctxs) {
    List<TerminalNode> visibilityModifiers = new LinkedList<TerminalNode>();
    int modifiers = 0;
    for (int i = 0; i < ctxs.size(); i++) {
        for (Object ctx : ctxs.get(i).children) {
            ParseTree child = null;//  ww w . j  ava2  s.  c o m
            if (ctx instanceof List) {
                List list = (List) ctx;
                assert list.size() == 1;
                child = (ParseTree) list.get(0);
            } else
                child = (ParseTree) ctx;

            assert child instanceof TerminalNode;
            switch (((TerminalNode) child).getSymbol().getType()) {
            case GroovyLangLexer.VISIBILITY_MODIFIER:
                visibilityModifiers.add((TerminalNode) child);
                break;
            case GroovyLangLexer.KW_STATIC:
                modifiers |= checkModifierDuplication(modifiers, Opcodes.ACC_STATIC, (TerminalNode) child);
                break;
            case GroovyLangLexer.KW_ABSTRACT:
                modifiers |= checkModifierDuplication(modifiers, Opcodes.ACC_ABSTRACT, (TerminalNode) child);
                break;
            case GroovyLangLexer.KW_FINAL:
                modifiers |= checkModifierDuplication(modifiers, Opcodes.ACC_FINAL, (TerminalNode) child);
                break;
            case GroovyLangLexer.KW_STRICTFP:
                modifiers |= checkModifierDuplication(modifiers, Opcodes.ACC_STRICT, (TerminalNode) child);
                break;
            }
        }
    }

    if (asBoolean(visibilityModifiers))
        modifiers |= parseVisibilityModifiers(visibilityModifiers, 0);
    else
        modifiers |= Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC;
    return modifiers;
}

From source file:org.codehaus.groovy.parser.antlr4.ASTBuilder.java

License:Apache License

/**
 * Traverse through modifiers, and combine them in one int value. Raise an error if there is multiple occurrences of same modifier.
 *
 * @param ctxList                   modifiers list.
 * @param defaultVisibilityModifier Default visibility modifier. Can be null. Applied if providen, and no visibility modifier exists in the ctxList.
 * @return tuple of int modifier and boolean flag, signalising visibility modifiers presence(true if there is visibility modifier in list, false otherwise).
 * @see #checkModifierDuplication(int, int, TerminalNode)
 *///from   w  w w  .  j  a  v  a  2  s .  co m
public List<Object> parseModifiers(List<? extends GroovyLangParser.MemberModifierContext> ctxList,
        Integer defaultVisibilityModifier) {
    int modifiers = 0;
    boolean hasVisibilityModifier = false;
    for (GroovyLangParser.MemberModifierContext it : ctxList) {
        TerminalNode child = (TerminalNode) it.getChild(0);
        switch (child.getSymbol().getType()) {
        case GroovyLangLexer.KW_STATIC:
            modifiers |= checkModifierDuplication(modifiers, Opcodes.ACC_STATIC, child);
            break;
        case GroovyLangLexer.KW_ABSTRACT:
            modifiers |= checkModifierDuplication(modifiers, Opcodes.ACC_ABSTRACT, child);
            break;
        case GroovyLangLexer.KW_FINAL:
            modifiers |= checkModifierDuplication(modifiers, Opcodes.ACC_FINAL, child);
            break;
        case GroovyLangLexer.KW_NATIVE:
            modifiers |= checkModifierDuplication(modifiers, Opcodes.ACC_NATIVE, child);
            break;
        case GroovyLangLexer.KW_SYNCHRONIZED:
            modifiers |= checkModifierDuplication(modifiers, Opcodes.ACC_SYNCHRONIZED, child);
            break;
        case GroovyLangLexer.KW_TRANSIENT:
            modifiers |= checkModifierDuplication(modifiers, Opcodes.ACC_TRANSIENT, child);
            break;
        case GroovyLangLexer.KW_VOLATILE:
            modifiers |= checkModifierDuplication(modifiers, Opcodes.ACC_VOLATILE, child);
            break;
        case GroovyLangLexer.VISIBILITY_MODIFIER:
            modifiers |= parseVisibilityModifiers(child);
            hasVisibilityModifier = true;
            break;
        }
    }
    if (!hasVisibilityModifier && defaultVisibilityModifier != null)
        modifiers |= defaultVisibilityModifier;

    return new LinkedList<Object>(Arrays.asList(modifiers, hasVisibilityModifier));
}

From source file:org.codehaus.groovy.tools.javac.JavaStubGenerator.java

License:Apache License

private void printClassContents(PrintWriter out, ClassNode classNode) {
    if (classNode instanceof InnerClassNode && ((InnerClassNode) classNode).isAnonymous()) {
        // if it is an anonymous inner class, don't generate the stub code for it.
        return;/* www.j a v  a 2  s.  c o  m*/
    }
    try {
        Verifier verifier = new Verifier() {
            @Override
            public void visitClass(ClassNode node) {
                List<Statement> savedStatements = new ArrayList<>(node.getObjectInitializerStatements());
                super.visitClass(node);
                node.getObjectInitializerStatements().addAll(savedStatements);

                for (ClassNode trait : findTraits(node)) {
                    // GROOVY-9031: replace property type placeholder with resolved type from trait generics
                    Map<String, ClassNode> generics = trait.isUsingGenerics() ? createGenericsSpec(trait)
                            : null;
                    for (PropertyNode traitProperty : trait.getProperties()) {
                        ClassNode traitPropertyType = traitProperty.getType();
                        traitProperty.setType(correctToGenericsSpec(generics, traitPropertyType));
                        super.visitProperty(traitProperty);
                        traitProperty.setType(traitPropertyType);
                    }
                }
            }

            private Iterable<ClassNode> findTraits(ClassNode node) {
                Set<ClassNode> traits = new LinkedHashSet<>();

                LinkedList<ClassNode> todo = new LinkedList<>();
                Collections.addAll(todo, node.getInterfaces());
                while (!todo.isEmpty()) {
                    ClassNode next = todo.removeLast();
                    if (Traits.isTrait(next))
                        traits.add(next);
                    Collections.addAll(todo, next.getInterfaces());
                }

                return traits;
            }

            @Override
            public void visitConstructor(ConstructorNode node) {
                Statement stmt = node.getCode();
                if (stmt != null) {
                    stmt.visit(new VerifierCodeVisitor(getClassNode()));
                }
            }

            @Override
            public void visitProperty(PropertyNode node) {
                // GROOVY-8233 skip static properties for traits since they don't make the interface
                if (!node.isStatic() || !Traits.isTrait(node.getDeclaringClass())) {
                    super.visitProperty(node);
                }
            }

            public void addCovariantMethods(ClassNode cn) {
            }

            protected void addInitialization(ClassNode node) {
            }

            protected void addPropertyMethod(MethodNode method) {
                doAddMethod(method);
            }

            protected void addReturnIfNeeded(MethodNode node) {
            }

            protected MethodNode addMethod(ClassNode node, boolean shouldBeSynthetic, String name,
                    int modifiers, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions,
                    Statement code) {
                return doAddMethod(new MethodNode(name, modifiers, returnType, parameters, exceptions, code));
            }

            protected void addConstructor(Parameter[] newParams, ConstructorNode ctor, Statement code,
                    ClassNode node) {
                if (code instanceof ExpressionStatement) {//GROOVY-4508
                    Statement temp = code;
                    code = new BlockStatement();
                    ((BlockStatement) code).addStatement(temp);
                }
                ConstructorNode ctrNode = new ConstructorNode(ctor.getModifiers(), newParams,
                        ctor.getExceptions(), code);
                ctrNode.setDeclaringClass(node);
                constructors.add(ctrNode);
            }

            protected void addDefaultParameters(DefaultArgsAction action, MethodNode method) {
                final Parameter[] parameters = method.getParameters();
                final Expression[] saved = new Expression[parameters.length];
                for (int i = 0; i < parameters.length; i++) {
                    if (parameters[i].hasInitialExpression())
                        saved[i] = parameters[i].getInitialExpression();
                }
                super.addDefaultParameters(action, method);
                for (int i = 0; i < parameters.length; i++) {
                    if (saved[i] != null)
                        parameters[i].setInitialExpression(saved[i]);
                }
            }

            private MethodNode doAddMethod(MethodNode method) {
                String sig = method.getTypeDescriptor();

                if (propertyMethodsWithSigs.containsKey(sig))
                    return method;

                propertyMethods.add(method);
                propertyMethodsWithSigs.put(sig, method);

                return method;
            }

            @Override
            protected void addDefaultConstructor(ClassNode node) {
                // not required for stub generation
            }

            @Override
            protected FinalVariableAnalyzer.VariableNotFinalCallback getFinalVariablesCallback() {
                return null;
            }
        };
        int origNumConstructors = classNode.getDeclaredConstructors().size();
        verifier.visitClass(classNode);
        // undo unwanted side-effect of verifier
        if (origNumConstructors == 0 && classNode.getDeclaredConstructors().size() == 1) {
            classNode.getDeclaredConstructors().clear();
        }
        currentModule = classNode.getModule();

        boolean isInterface = isInterfaceOrTrait(classNode);
        boolean isEnum = classNode.isEnum();
        boolean isAnnotationDefinition = classNode.isAnnotationDefinition();
        printAnnotations(out, classNode);
        printModifiers(out, classNode.getModifiers() & ~(isInterface ? Opcodes.ACC_ABSTRACT : 0)
                & ~(isEnum ? Opcodes.ACC_FINAL | Opcodes.ACC_ABSTRACT : 0));

        if (isInterface) {
            if (isAnnotationDefinition) {
                out.print("@");
            }
            out.print("interface ");
        } else if (isEnum) {
            out.print("enum ");
        } else {
            out.print("class ");
        }

        String className = classNode.getNameWithoutPackage();
        if (classNode instanceof InnerClassNode)
            className = className.substring(className.lastIndexOf("$") + 1);
        out.println(className);
        printGenericsBounds(out, classNode, true);

        ClassNode superClass = classNode.getUnresolvedSuperClass(false);

        if (!isInterface && !isEnum) {
            out.print("  extends ");
            printType(out, superClass);
        }

        ClassNode[] interfaces = classNode.getInterfaces();
        if (interfaces != null && interfaces.length > 0 && !isAnnotationDefinition) {
            if (isInterface) {
                out.println("  extends");
            } else {
                out.println("  implements");
            }
            for (int i = 0; i < interfaces.length - 1; ++i) {
                out.print("    ");
                printType(out, interfaces[i]);
                out.print(",");
            }
            out.print("    ");
            printType(out, interfaces[interfaces.length - 1]);
        }
        out.println(" {");

        printFields(out, classNode);
        printMethods(out, classNode, isEnum);

        for (Iterator<InnerClassNode> inner = classNode.getInnerClasses(); inner.hasNext();) {
            // GROOVY-4004: Clear the methods from the outer class so that they don't get duplicated in inner ones
            propertyMethods.clear();
            propertyMethodsWithSigs.clear();
            constructors.clear();
            printClassContents(out, inner.next());
        }

        out.println("}");
    } finally {
        propertyMethods.clear();
        propertyMethodsWithSigs.clear();
        constructors.clear();
        currentModule = null;
    }
}