Search in sources :

Example 26 with GenericsType

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

the class StaticTypeCheckingVisitor method getTypeForMapPropertyExpression.

private ClassNode getTypeForMapPropertyExpression(ClassNode testClass, ClassNode objectExpressionType, PropertyExpression pexp) {
    if (!implementsInterfaceOrIsSubclassOf(testClass, MAP_TYPE))
        return null;
    ClassNode intf;
    if (objectExpressionType.getGenericsTypes() != null) {
        intf = GenericsUtils.parameterizeType(objectExpressionType, MAP_TYPE.getPlainNodeReference());
    } else {
        intf = MAP_TYPE.getPlainNodeReference();
    }
    // 0 is the key, 1 is the value
    GenericsType[] types = intf.getGenericsTypes();
    if (types == null || types.length != 2)
        return OBJECT_TYPE;
    if (pexp.isSpreadSafe()) {
        // only "key" and "value" are allowed
        if ("key".equals(pexp.getPropertyAsString())) {
            ClassNode listKey = LIST_TYPE.getPlainNodeReference();
            listKey.setGenericsTypes(new GenericsType[] { types[0] });
            return listKey;
        } else if ("value".equals(pexp.getPropertyAsString())) {
            ClassNode listValue = LIST_TYPE.getPlainNodeReference();
            listValue.setGenericsTypes(new GenericsType[] { types[1] });
            return listValue;
        } else {
            addStaticTypeError("Spread operator on map only allows one of [key,value]", pexp);
        }
    } else {
        return types[1].getType();
    }
    return null;
}
Also used : LowestUpperBoundClassNode(org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) GenericsType(org.codehaus.groovy.ast.GenericsType)

Example 27 with GenericsType

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

the class TraitASTTransformation method createReceiverType.

private static ClassNode createReceiverType(final boolean isStatic, final ClassNode rawType) {
    ClassNode type;
    if (isStatic) {
        // Class<TraitClass>
        type = ClassHelper.CLASS_Type.getPlainNodeReference();
        type.setGenericsTypes(new GenericsType[] { new GenericsType(rawType) });
    } else {
        // TraitClass
        type = rawType;
    }
    return type;
}
Also used : InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) GenericsType(org.codehaus.groovy.ast.GenericsType)

Example 28 with GenericsType

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

the class StaticTypeCheckingSupport method compatibleConnections.

private static boolean compatibleConnections(Map<String, GenericsType> connections, Map<String, GenericsType> resolvedMethodGenerics, Set<String> fixedGenericsPlaceHolders) {
    for (Map.Entry<String, GenericsType> entry : connections.entrySet()) {
        GenericsType resolved = resolvedMethodGenerics.get(entry.getKey());
        if (resolved == null)
            continue;
        GenericsType connection = entry.getValue();
        if (connection.isPlaceholder() && !hasNonTrivialBounds(connection)) {
            continue;
        }
        if (!compatibleConnection(resolved, connection)) {
            if (!(resolved.isPlaceholder() || resolved.isWildcard()) && !fixedGenericsPlaceHolders.contains(entry.getKey()) && compatibleConnection(connection, resolved)) {
                // we did for example find T=String and now check against
                // T=Object, which fails the first compatibleConnection check
                // but since T=Object works for both, the second one will pass
                // and we need to change the type for T to the more general one
                resolvedMethodGenerics.put(entry.getKey(), connection);
            } else {
                return false;
            }
        }
    }
    return true;
}
Also used : GenericsType(org.codehaus.groovy.ast.GenericsType) Map(java.util.Map) HashMap(java.util.HashMap)

Example 29 with GenericsType

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

the class StaticTypeCheckingSupport method extractGenericsConnections.

private static void extractGenericsConnections(Map<String, GenericsType> connections, ClassNode[] usage, ClassNode[] declaration) {
    if (usage == null || declaration == null || declaration.length == 0)
        return;
    // both have generics
    for (int i = 0; i < usage.length; i++) {
        ClassNode ui = usage[i];
        ClassNode di = declaration[i];
        if (di.isGenericsPlaceHolder()) {
            GenericsType gt = new GenericsType(di);
            gt.setPlaceholder(di.isGenericsPlaceHolder());
            connections.put(di.getGenericsTypes()[0].getName(), gt);
        } else if (di.isUsingGenerics()) {
            extractGenericsConnections(connections, ui.getGenericsTypes(), di.getGenericsTypes());
        }
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) GenericsType(org.codehaus.groovy.ast.GenericsType)

Example 30 with GenericsType

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

the class StaticTypeCheckingSupport method fullyResolve.

/**
     * Given a generics type representing SomeClass&lt;T,V&gt; and a resolved placeholder map, returns a new generics type
     * for which placeholders are resolved recursively.
     */
protected static GenericsType fullyResolve(GenericsType gt, Map<String, GenericsType> placeholders) {
    GenericsType fromMap = placeholders.get(gt.getName());
    if (gt.isPlaceholder() && fromMap != null) {
        gt = fromMap;
    }
    ClassNode type = fullyResolveType(gt.getType(), placeholders);
    ClassNode lowerBound = gt.getLowerBound();
    if (lowerBound != null)
        lowerBound = fullyResolveType(lowerBound, placeholders);
    ClassNode[] upperBounds = gt.getUpperBounds();
    if (upperBounds != null) {
        ClassNode[] copy = new ClassNode[upperBounds.length];
        for (int i = 0, upperBoundsLength = upperBounds.length; i < upperBoundsLength; i++) {
            final ClassNode upperBound = upperBounds[i];
            copy[i] = fullyResolveType(upperBound, placeholders);
        }
        upperBounds = copy;
    }
    GenericsType genericsType = new GenericsType(type, upperBounds, lowerBound);
    genericsType.setWildcard(gt.isWildcard());
    return genericsType;
}
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