Search in sources :

Example 66 with GenericsType

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

the class AntlrParserPlugin method methodDef.

protected void methodDef(AST methodDef) {
    MethodNode oldNode = methodNode;
    List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
    AST node = methodDef.getFirstChild();
    GenericsType[] generics = null;
    if (isType(TYPE_PARAMETERS, node)) {
        generics = makeGenericsType(node);
        node = node.getNextSibling();
    }
    int modifiers = Opcodes.ACC_PUBLIC;
    if (isType(MODIFIERS, node)) {
        modifiers = modifiers(node, annotations, modifiers);
        checkNoInvalidModifier(methodDef, "Method", modifiers, Opcodes.ACC_VOLATILE, "volatile");
        node = node.getNextSibling();
    }
    if (isAnInterface()) {
        modifiers |= Opcodes.ACC_ABSTRACT;
    }
    ClassNode returnType = null;
    if (isType(TYPE, node)) {
        returnType = makeTypeWithArguments(node);
        node = node.getNextSibling();
    }
    String name = identifier(node);
    if (classNode != null && !classNode.isAnnotationDefinition()) {
        if (classNode.getNameWithoutPackage().equals(name)) {
            if (isAnInterface()) {
                throw new ASTRuntimeException(methodDef, "Constructor not permitted within an interface.");
            }
            throw new ASTRuntimeException(methodDef, "Invalid constructor format. Remove '" + returnType.getName() + "' as the return type if you want a constructor, or use a different name if you want a method.");
        }
    }
    node = node.getNextSibling();
    Parameter[] parameters = Parameter.EMPTY_ARRAY;
    ClassNode[] exceptions = ClassNode.EMPTY_ARRAY;
    if (classNode == null || !classNode.isAnnotationDefinition()) {
        assertNodeType(PARAMETERS, node);
        parameters = parameters(node);
        if (parameters == null)
            parameters = Parameter.EMPTY_ARRAY;
        node = node.getNextSibling();
        if (isType(LITERAL_throws, node)) {
            AST throwsNode = node.getFirstChild();
            List<ClassNode> exceptionList = new ArrayList<ClassNode>();
            throwsList(throwsNode, exceptionList);
            exceptions = exceptionList.toArray(exceptions);
            node = node.getNextSibling();
        }
    }
    boolean hasAnnotationDefault = false;
    Statement code = null;
    boolean syntheticPublic = ((modifiers & Opcodes.ACC_SYNTHETIC) != 0);
    modifiers &= ~Opcodes.ACC_SYNTHETIC;
    methodNode = new MethodNode(name, modifiers, returnType, parameters, exceptions, code);
    if ((modifiers & Opcodes.ACC_ABSTRACT) == 0) {
        if (node == null) {
            throw new ASTRuntimeException(methodDef, "You defined a method without body. Try adding a body, or declare it abstract.");
        }
        assertNodeType(SLIST, node);
        code = statementList(node);
    } else if (node != null && classNode.isAnnotationDefinition()) {
        code = statement(node);
        hasAnnotationDefault = true;
    } else if ((modifiers & Opcodes.ACC_ABSTRACT) > 0) {
        if (node != null) {
            throw new ASTRuntimeException(methodDef, "Abstract methods do not define a body.");
        }
    }
    methodNode.setCode(code);
    methodNode.addAnnotations(annotations);
    methodNode.setGenericsTypes(generics);
    methodNode.setAnnotationDefault(hasAnnotationDefault);
    methodNode.setSyntheticPublic(syntheticPublic);
    configureAST(methodNode, methodDef);
    if (classNode != null) {
        classNode.addMethod(methodNode);
    } else {
        output.addMethod(methodNode);
    }
    methodNode = oldNode;
}
Also used : EnumConstantClassNode(org.codehaus.groovy.ast.EnumConstantClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) AST(antlr.collections.AST) CaseStatement(org.codehaus.groovy.ast.stmt.CaseStatement) ForStatement(org.codehaus.groovy.ast.stmt.ForStatement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) AssertStatement(org.codehaus.groovy.ast.stmt.AssertStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Statement(org.codehaus.groovy.ast.stmt.Statement) WhileStatement(org.codehaus.groovy.ast.stmt.WhileStatement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement) ContinueStatement(org.codehaus.groovy.ast.stmt.ContinueStatement) BreakStatement(org.codehaus.groovy.ast.stmt.BreakStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) SynchronizedStatement(org.codehaus.groovy.ast.stmt.SynchronizedStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) SwitchStatement(org.codehaus.groovy.ast.stmt.SwitchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) ArrayList(java.util.ArrayList) MethodNode(org.codehaus.groovy.ast.MethodNode) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) GenericsType(org.codehaus.groovy.ast.GenericsType) Parameter(org.codehaus.groovy.ast.Parameter)

Example 67 with GenericsType

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

the class InitializerStrategy method createBuilderMethodForField.

private MethodNode createBuilderMethodForField(ClassNode builder, List<FieldNode> fields, String prefix, int fieldPos) {
    String fieldName = fields.get(fieldPos).getName();
    String setterName = getSetterName(prefix, fieldName);
    GenericsType[] gtypes = new GenericsType[fields.size()];
    List<Expression> argList = new ArrayList<Expression>();
    for (int i = 0; i < fields.size(); i++) {
        gtypes[i] = i == fieldPos ? new GenericsType(ClassHelper.make(SET.class)) : makePlaceholder(i);
        argList.add(i == fieldPos ? propX(varX("this"), constX(fieldName)) : varX(fields.get(i).getName()));
    }
    ClassNode returnType = makeClassSafeWithGenerics(builder, gtypes);
    FieldNode fNode = fields.get(fieldPos);
    Map<String, ClassNode> genericsSpec = createGenericsSpec(fNode.getDeclaringClass());
    extractSuperClassGenerics(fNode.getType(), builder, genericsSpec);
    ClassNode correctedType = correctToGenericsSpecRecurse(genericsSpec, fNode.getType());
    return new MethodNode(setterName, ACC_PUBLIC, returnType, params(param(correctedType, fieldName)), NO_EXCEPTIONS, block(stmt(assignX(propX(varX("this"), constX(fieldName)), varX(fieldName, correctedType))), returnS(ctorX(returnType, args(argList)))));
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) MethodNode(org.codehaus.groovy.ast.MethodNode) Expression(org.codehaus.groovy.ast.expr.Expression) GenericsType(org.codehaus.groovy.ast.GenericsType) ArrayList(java.util.ArrayList)

Example 68 with GenericsType

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

the class WideningCategories method areEqualWithGenerics.

/**
     * Compares two class nodes, but including their generics types.
     * @param a
     * @param b
     * @return true if the class nodes are equal, false otherwise
     */
private static boolean areEqualWithGenerics(ClassNode a, ClassNode b) {
    if (a == null)
        return b == null;
    if (!a.equals(b))
        return false;
    if (a.isUsingGenerics() && !b.isUsingGenerics())
        return false;
    GenericsType[] gta = a.getGenericsTypes();
    GenericsType[] gtb = b.getGenericsTypes();
    if (gta == null && gtb != null)
        return false;
    if (gtb == null && gta != null)
        return false;
    if (gta != null && gtb != null) {
        if (gta.length != gtb.length)
            return false;
        for (int i = 0; i < gta.length; i++) {
            GenericsType ga = gta[i];
            GenericsType gb = gtb[i];
            boolean result = ga.isPlaceholder() == gb.isPlaceholder() && ga.isWildcard() == gb.isWildcard();
            result = result && ga.isResolved() && gb.isResolved();
            result = result && ga.getName().equals(gb.getName());
            result = result && areEqualWithGenerics(ga.getType(), gb.getType());
            result = result && areEqualWithGenerics(ga.getLowerBound(), gb.getLowerBound());
            if (result) {
                ClassNode[] upA = ga.getUpperBounds();
                if (upA != null) {
                    ClassNode[] upB = gb.getUpperBounds();
                    if (upB == null || upB.length != upA.length)
                        return false;
                    for (int j = 0; j < upA.length; j++) {
                        if (!areEqualWithGenerics(upA[j], upB[j]))
                            return false;
                    }
                }
            }
            if (!result)
                return false;
        }
    }
    return true;
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) GenericsType(org.codehaus.groovy.ast.GenericsType)

Example 69 with GenericsType

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

the class AntlrParserPlugin method innerInterfaceDef.

protected void innerInterfaceDef(AST classDef) {
    List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
    AST node = classDef.getFirstChild();
    int modifiers = Opcodes.ACC_PUBLIC;
    if (isType(MODIFIERS, node)) {
        modifiers = modifiers(node, annotations, modifiers);
        checkNoInvalidModifier(classDef, "Interface", modifiers, Opcodes.ACC_SYNCHRONIZED, "synchronized");
        node = node.getNextSibling();
    }
    modifiers |= Opcodes.ACC_ABSTRACT | Opcodes.ACC_INTERFACE;
    String name = identifier(node);
    node = node.getNextSibling();
    ClassNode superClass = ClassHelper.OBJECT_TYPE;
    GenericsType[] genericsType = null;
    if (isType(TYPE_PARAMETERS, node)) {
        genericsType = makeGenericsType(node);
        node = node.getNextSibling();
    }
    ClassNode[] interfaces = ClassNode.EMPTY_ARRAY;
    if (isType(EXTENDS_CLAUSE, node)) {
        interfaces = interfaces(node);
        node = node.getNextSibling();
    }
    ClassNode outerClass = classNode;
    boolean syntheticPublic = ((modifiers & Opcodes.ACC_SYNTHETIC) != 0);
    modifiers &= ~Opcodes.ACC_SYNTHETIC;
    if (classNode != null) {
        name = classNode.getNameWithoutPackage() + "$" + name;
        String fullName = dot(classNode.getPackageName(), name);
        classNode = new InnerClassNode(classNode, fullName, modifiers, superClass, interfaces, null);
    } else {
        classNode = new ClassNode(dot(getPackageName(), name), modifiers, superClass, interfaces, null);
    }
    classNode.setSyntheticPublic(syntheticPublic);
    classNode.addAnnotations(annotations);
    classNode.setGenericsTypes(genericsType);
    configureAST(classNode, classDef);
    int oldClassCount = innerClassCounter;
    assertNodeType(OBJBLOCK, node);
    objectBlock(node);
    output.addClass(classNode);
    classNode = outerClass;
    innerClassCounter = oldClassCount;
}
Also used : EnumConstantClassNode(org.codehaus.groovy.ast.EnumConstantClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) AST(antlr.collections.AST) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) ArrayList(java.util.ArrayList) GenericsType(org.codehaus.groovy.ast.GenericsType) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode)

Example 70 with GenericsType

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

the class GenericsUtils method correctToGenericsSpecRecurse.

public static ClassNode correctToGenericsSpecRecurse(Map<String, ClassNode> genericsSpec, ClassNode type, List<String> exclusions) {
    if (type.isArray()) {
        return correctToGenericsSpecRecurse(genericsSpec, type.getComponentType(), exclusions).makeArray();
    }
    if (type.isGenericsPlaceHolder() && !exclusions.contains(type.getUnresolvedName())) {
        String name = type.getGenericsTypes()[0].getName();
        type = genericsSpec.get(name);
        if (type != null && type.isGenericsPlaceHolder() && type.getGenericsTypes() == null) {
            ClassNode placeholder = ClassHelper.makeWithoutCaching(type.getUnresolvedName());
            placeholder.setGenericsPlaceHolder(true);
            type = makeClassSafeWithGenerics(type, new GenericsType(placeholder));
        }
    }
    if (type == null)
        type = ClassHelper.OBJECT_TYPE;
    GenericsType[] oldgTypes = type.getGenericsTypes();
    GenericsType[] newgTypes = GenericsType.EMPTY_ARRAY;
    if (oldgTypes != null) {
        newgTypes = new GenericsType[oldgTypes.length];
        for (int i = 0; i < newgTypes.length; i++) {
            GenericsType oldgType = oldgTypes[i];
            if (oldgType.isPlaceholder()) {
                if (genericsSpec.get(oldgType.getName()) != null) {
                    newgTypes[i] = new GenericsType(genericsSpec.get(oldgType.getName()));
                } else {
                    newgTypes[i] = new GenericsType(ClassHelper.OBJECT_TYPE);
                }
            } else if (oldgType.isWildcard()) {
                ClassNode oldLower = oldgType.getLowerBound();
                ClassNode lower = oldLower != null ? correctToGenericsSpecRecurse(genericsSpec, oldLower, exclusions) : null;
                ClassNode[] oldUpper = oldgType.getUpperBounds();
                ClassNode[] upper = null;
                if (oldUpper != null) {
                    upper = new ClassNode[oldUpper.length];
                    for (int j = 0; j < oldUpper.length; j++) {
                        upper[j] = correctToGenericsSpecRecurse(genericsSpec, oldUpper[j], exclusions);
                    }
                }
                GenericsType fixed = new GenericsType(oldgType.getType(), upper, lower);
                fixed.setName(oldgType.getName());
                fixed.setWildcard(true);
                newgTypes[i] = fixed;
            } else {
                newgTypes[i] = new GenericsType(correctToGenericsSpecRecurse(genericsSpec, correctToGenericsSpec(genericsSpec, oldgType), exclusions));
            }
        }
    }
    return makeClassSafeWithGenerics(type, newgTypes);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) GenericsType(org.codehaus.groovy.ast.GenericsType)

Aggregations

GenericsType (org.codehaus.groovy.ast.GenericsType)171 ClassNode (org.codehaus.groovy.ast.ClassNode)148 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)76 LowestUpperBoundClassNode (org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode)52 Parameter (org.codehaus.groovy.ast.Parameter)21 MethodNode (org.codehaus.groovy.ast.MethodNode)20 ClosureSignatureHint (groovy.transform.stc.ClosureSignatureHint)19 LinkedList (java.util.LinkedList)18 HashMap (java.util.HashMap)17 ArrayList (java.util.ArrayList)15 LinkedHashMap (java.util.LinkedHashMap)9 AST (antlr.collections.AST)8 AnnotationNode (org.codehaus.groovy.ast.AnnotationNode)8 ListHashMap (org.codehaus.groovy.util.ListHashMap)8 Map (java.util.Map)6 AtomicReference (java.util.concurrent.atomic.AtomicReference)6 EnumConstantClassNode (org.codehaus.groovy.ast.EnumConstantClassNode)6 FieldNode (org.codehaus.groovy.ast.FieldNode)6 GroovyBugError (org.codehaus.groovy.GroovyBugError)5 DynamicVariable (org.codehaus.groovy.ast.DynamicVariable)4