Search in sources :

Example 1 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 2 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 3 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)

Example 4 with GenericsType

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

the class GenericsUtils method parseClassNodesFromString.

public static ClassNode[] parseClassNodesFromString(final String option, final SourceUnit sourceUnit, final CompilationUnit compilationUnit, final MethodNode mn, final ASTNode usage) {
    GroovyLexer lexer = new GroovyLexer(new StringReader("DummyNode<" + option + ">"));
    final GroovyRecognizer rn = GroovyRecognizer.make(lexer);
    try {
        rn.classOrInterfaceType(true);
        final AtomicReference<ClassNode> ref = new AtomicReference<ClassNode>();
        AntlrParserPlugin plugin = new AntlrParserPlugin() {

            @Override
            public ModuleNode buildAST(final SourceUnit sourceUnit, final ClassLoader classLoader, final Reduction cst) throws ParserException {
                ref.set(makeTypeWithArguments(rn.getAST()));
                return null;
            }
        };
        plugin.buildAST(null, null, null);
        ClassNode parsedNode = ref.get();
        // the returned node is DummyNode<Param1, Param2, Param3, ...)
        GenericsType[] parsedNodeGenericsTypes = parsedNode.getGenericsTypes();
        if (parsedNodeGenericsTypes == null) {
            return null;
        }
        ClassNode[] signature = new ClassNode[parsedNodeGenericsTypes.length];
        for (int i = 0; i < parsedNodeGenericsTypes.length; i++) {
            final GenericsType genericsType = parsedNodeGenericsTypes[i];
            signature[i] = resolveClassNode(sourceUnit, compilationUnit, mn, usage, genericsType.getType());
        }
        return signature;
    } catch (RecognitionException e) {
        sourceUnit.addError(new IncorrectTypeHintException(mn, e, usage.getLineNumber(), usage.getColumnNumber()));
    } catch (TokenStreamException e) {
        sourceUnit.addError(new IncorrectTypeHintException(mn, e, usage.getLineNumber(), usage.getColumnNumber()));
    } catch (ParserException e) {
        sourceUnit.addError(new IncorrectTypeHintException(mn, e, usage.getLineNumber(), usage.getColumnNumber()));
    }
    return null;
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) ParserException(org.codehaus.groovy.syntax.ParserException) IncorrectTypeHintException(groovy.transform.stc.IncorrectTypeHintException) AtomicReference(java.util.concurrent.atomic.AtomicReference) SourceUnit(org.codehaus.groovy.control.SourceUnit) TokenStreamException(antlr.TokenStreamException) Reduction(org.codehaus.groovy.syntax.Reduction) AntlrParserPlugin(org.codehaus.groovy.antlr.AntlrParserPlugin) GroovyLexer(org.codehaus.groovy.antlr.parser.GroovyLexer) StringReader(java.io.StringReader) GenericsType(org.codehaus.groovy.ast.GenericsType) GroovyRecognizer(org.codehaus.groovy.antlr.parser.GroovyRecognizer) RecognitionException(antlr.RecognitionException)

Example 5 with GenericsType

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

the class GenericsUtils method extractSuperClassGenerics.

private static void extractSuperClassGenerics(GenericsType[] usage, GenericsType[] declaration, Map<String, ClassNode> spec) {
    // if declaration does not provide generics, there is no connection to make 
    if (usage == null || declaration == null || declaration.length == 0)
        return;
    if (usage.length != declaration.length)
        return;
    // both have generics
    for (int i = 0; i < usage.length; i++) {
        GenericsType ui = usage[i];
        GenericsType di = declaration[i];
        if (di.isPlaceholder()) {
            spec.put(di.getName(), ui.getType());
        } else if (di.isWildcard()) {
            if (ui.isWildcard()) {
                extractSuperClassGenerics(ui.getLowerBound(), di.getLowerBound(), spec);
                extractSuperClassGenerics(ui.getUpperBounds(), di.getUpperBounds(), spec);
            } else {
                ClassNode cu = ui.getType();
                extractSuperClassGenerics(cu, di.getLowerBound(), spec);
                ClassNode[] upperBounds = di.getUpperBounds();
                if (upperBounds != null) {
                    for (ClassNode cn : upperBounds) {
                        extractSuperClassGenerics(cu, cn, spec);
                    }
                }
            }
        } else {
            extractSuperClassGenerics(ui.getType(), di.getType(), spec);
        }
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) GenericsType(org.codehaus.groovy.ast.GenericsType)

Aggregations

GenericsType (org.codehaus.groovy.ast.GenericsType)165 ClassNode (org.codehaus.groovy.ast.ClassNode)143 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)71 LowestUpperBoundClassNode (org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode)52 Parameter (org.codehaus.groovy.ast.Parameter)20 ClosureSignatureHint (groovy.transform.stc.ClosureSignatureHint)19 MethodNode (org.codehaus.groovy.ast.MethodNode)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