Search in sources :

Example 66 with InnerClassNode

use of org.codehaus.groovy.ast.InnerClassNode in project groovy by apache.

the class EnumHelper method makeEnumNode.

public static ClassNode makeEnumNode(String name, int modifiers, ClassNode[] interfaces, ClassNode outerClass) {
    modifiers = modifiers | Opcodes.ACC_FINAL | Opcodes.ACC_ENUM;
    ClassNode enumClass;
    if (outerClass == null) {
        enumClass = new ClassNode(name, modifiers, null, interfaces, MixinNode.EMPTY_ARRAY);
    } else {
        name = outerClass.getName() + "$" + name;
        modifiers |= Opcodes.ACC_STATIC;
        enumClass = new InnerClassNode(outerClass, name, modifiers, null, interfaces, MixinNode.EMPTY_ARRAY);
    }
    // set super class and generics info
    // "enum X" -> class X extends Enum<X>
    GenericsType gt = new GenericsType(enumClass);
    ClassNode superClass = ClassHelper.makeWithoutCaching("java.lang.Enum");
    superClass.setGenericsTypes(new GenericsType[] { gt });
    enumClass.setSuperClass(superClass);
    superClass.setRedirect(ClassHelper.Enum_Type);
    return enumClass;
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) GenericsType(org.codehaus.groovy.ast.GenericsType) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode)

Example 67 with InnerClassNode

use of org.codehaus.groovy.ast.InnerClassNode in project groovy by apache.

the class JavaStubGenerator method printClassContents.

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;
    }
    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(correctToGenericsSpecRecurse(generics, traitPropertyType));
                        super.visitProperty(traitProperty);
                        traitProperty.setType(traitPropertyType);
                    }
                }
            }

            @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);
                }
            }

            @Override
            public void addCovariantMethods(ClassNode cn) {
            }

            @Override
            protected void addInitialization(ClassNode node) {
            }

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

            @Override
            protected void addReturnIfNeeded(MethodNode node) {
            }

            @Override
            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));
            }

            @Override
            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);
            }

            @Override
            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();
        }
        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();
    }
}
Also used : DecompiledClassNode(org.codehaus.groovy.ast.decompiled.DecompiledClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ArrayList(java.util.ArrayList) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Verifier(org.codehaus.groovy.classgen.Verifier) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) VerifierCodeVisitor(org.codehaus.groovy.classgen.VerifierCodeVisitor) MethodNode(org.codehaus.groovy.ast.MethodNode) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) PropertyNode(org.codehaus.groovy.ast.PropertyNode) ConstructorNode(org.codehaus.groovy.ast.ConstructorNode) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) Parameter(org.codehaus.groovy.ast.Parameter) FinalVariableAnalyzer(org.codehaus.groovy.classgen.FinalVariableAnalyzer)

Example 68 with InnerClassNode

use of org.codehaus.groovy.ast.InnerClassNode in project groovy by apache.

the class MacroGroovyMethods method buildSubstitutions.

public static ListExpression buildSubstitutions(final SourceUnit source, final ASTNode expr) {
    final ListExpression listExpression = new ListExpression();
    ClassCodeVisitorSupport visitor = new ClassCodeVisitorSupport() {

        @Override
        protected SourceUnit getSourceUnit() {
            return null;
        }

        @Override
        public void visitClass(final ClassNode node) {
            super.visitClass(node);
            Iterator<InnerClassNode> it = node.getInnerClasses();
            while (it.hasNext()) {
                InnerClassNode next = it.next();
                visitClass(next);
            }
        }

        @Override
        public void visitMethodCallExpression(MethodCallExpression call) {
            super.visitMethodCallExpression(call);
            if (DOLLAR_VALUE.equals(call.getMethodAsString())) {
                ClosureExpression substitutionClosureExpression = getClosureArgument(source, call);
                if (substitutionClosureExpression == null) {
                    return;
                }
                Statement code = substitutionClosureExpression.getCode();
                if (code instanceof BlockStatement) {
                    ((BlockStatement) code).setVariableScope(null);
                }
                listExpression.addExpression(substitutionClosureExpression);
            }
        }
    };
    if (expr instanceof ClassNode) {
        visitor.visitClass((ClassNode) expr);
    } else {
        expr.visit(visitor);
    }
    return listExpression;
}
Also used : ClassCodeVisitorSupport(org.codehaus.groovy.ast.ClassCodeVisitorSupport) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Statement(org.codehaus.groovy.ast.stmt.Statement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode)

Example 69 with InnerClassNode

use of org.codehaus.groovy.ast.InnerClassNode in project groovy by apache.

the class ResolveVisitor method checkThisAndSuperAsPropertyAccess.

private void checkThisAndSuperAsPropertyAccess(final PropertyExpression expression) {
    if (expression.isImplicitThis())
        return;
    String prop = expression.getPropertyAsString();
    if (prop == null)
        return;
    if (!prop.equals("this") && !prop.equals("super"))
        return;
    ClassNode type = expression.getObjectExpression().getType();
    if (expression.getObjectExpression() instanceof ClassExpression) {
        if (!(currentClass instanceof InnerClassNode) && !Traits.isTrait(type)) {
            addError("The usage of 'Class.this' and 'Class.super' is only allowed in nested/inner classes.", expression);
            return;
        }
        if (currentScope != null && !currentScope.isInStaticContext() && Traits.isTrait(type) && "super".equals(prop) && directlyImplementsTrait(type)) {
            return;
        }
        ClassNode iterType = currentClass;
        while (iterType != null) {
            if (iterType.equals(type))
                break;
            iterType = iterType.getOuterClass();
        }
        if (iterType == null) {
            addError("The class '" + type.getName() + "' needs to be an outer class of '" + currentClass.getName() + "' when using '.this' or '.super'.", expression);
        }
        if (!Modifier.isStatic(currentClass.getModifiers()))
            return;
        if (currentScope != null && !currentScope.isInStaticContext())
            return;
        addError("The usage of 'Class.this' and 'Class.super' within static nested class '" + currentClass.getName() + "' is not allowed in a static context.", expression);
    }
}
Also used : InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode)

Example 70 with InnerClassNode

use of org.codehaus.groovy.ast.InnerClassNode in project groovy by apache.

the class AsmClassGenerator method makeInnerClassEntry.

private void makeInnerClassEntry(final ClassNode cn) {
    if (!(cn instanceof InnerClassNode))
        return;
    InnerClassNode innerClass = (InnerClassNode) cn;
    String innerClassName = innerClass.getName();
    String innerClassInternalName = BytecodeHelper.getClassInternalName(innerClassName);
    {
        int index = innerClassName.lastIndexOf('$');
        if (index >= 0)
            innerClassName = innerClassName.substring(index + 1);
    }
    String outerClassName = BytecodeHelper.getClassInternalName(innerClass.getOuterClass().getName());
    MethodNode enclosingMethod = innerClass.getEnclosingMethod();
    if (enclosingMethod != null) {
        // local inner classes do not specify the outer class name
        outerClassName = null;
        if (innerClass.isAnonymous())
            innerClassName = null;
    }
    int modifiers = adjustedClassModifiersForInnerClassTable(cn);
    classVisitor.visitInnerClass(innerClassInternalName, outerClassName, innerClassName, modifiers);
}
Also used : MethodNode(org.codehaus.groovy.ast.MethodNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode)

Aggregations

InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)78 ClassNode (org.codehaus.groovy.ast.ClassNode)67 MethodNode (org.codehaus.groovy.ast.MethodNode)33 FieldNode (org.codehaus.groovy.ast.FieldNode)20 Parameter (org.codehaus.groovy.ast.Parameter)20 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)20 ArrayList (java.util.ArrayList)17 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)16 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)15 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)15 Expression (org.codehaus.groovy.ast.expr.Expression)15 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)14 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)13 Statement (org.codehaus.groovy.ast.stmt.Statement)13 ConstructorNode (org.codehaus.groovy.ast.ConstructorNode)12 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)12 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)11 EnumConstantClassNode (org.codehaus.groovy.ast.EnumConstantClassNode)10 GenericsType (org.codehaus.groovy.ast.GenericsType)10 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)9