Search in sources :

Example 46 with GenericsType

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

the class StaticTypeCheckingVisitor method adjustTypeForSpreading.

private static ClassNode adjustTypeForSpreading(ClassNode inferredRightExpressionType, Expression leftExpression) {
    // imagine we have: list*.foo = 100
    // then the assignment must be checked against [100], not 100
    ClassNode wrappedRHS = inferredRightExpressionType;
    if (leftExpression instanceof PropertyExpression && ((PropertyExpression) leftExpression).isSpreadSafe()) {
        wrappedRHS = LIST_TYPE.getPlainNodeReference();
        wrappedRHS.setGenericsTypes(new GenericsType[] { new GenericsType(getWrapper(inferredRightExpressionType)) });
    }
    return wrappedRHS;
}
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 47 with GenericsType

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

the class StaticTypeCheckingVisitor method inferListExpressionType.

protected ClassNode inferListExpressionType(final ListExpression list) {
    List<Expression> expressions = list.getExpressions();
    if (expressions.isEmpty()) {
        // cannot infer, return list type
        return list.getType();
    }
    ClassNode listType = list.getType();
    GenericsType[] genericsTypes = listType.getGenericsTypes();
    if ((genericsTypes == null || genericsTypes.length == 0 || (genericsTypes.length == 1 && OBJECT_TYPE.equals(genericsTypes[0].getType()))) && (!expressions.isEmpty())) {
        // maybe we can infer the component type
        List<ClassNode> nodes = new LinkedList<ClassNode>();
        for (Expression expression : expressions) {
            if (isNullConstant(expression)) {
            // a null element is found in the list, skip it because we'll use the other elements from the list
            } else {
                nodes.add(getType(expression));
            }
        }
        if (nodes.isEmpty()) {
            // every element was the null constant
            return listType;
        }
        // to be used in generics, type must be boxed
        ClassNode superType = getWrapper(lowestUpperBound(nodes));
        ClassNode inferred = listType.getPlainNodeReference();
        inferred.setGenericsTypes(new GenericsType[] { new GenericsType(wrapTypeIfNecessary(superType)) });
        return inferred;
    }
    return listType;
}
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) LinkedList(java.util.LinkedList)

Example 48 with GenericsType

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

the class StaticTypeCheckingVisitor method wrapClosureType.

private static ClassNode wrapClosureType(final ClassNode returnType) {
    ClassNode inferredType = CLOSURE_TYPE.getPlainNodeReference();
    inferredType.setGenericsTypes(new GenericsType[] { new GenericsType(wrapTypeIfNecessary(returnType)) });
    return inferredType;
}
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 49 with GenericsType

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

the class StaticTypeCheckingVisitor method inferLoopElementType.

/**
     * Given a loop collection type, returns the inferred type of the loop element. Used, for
     * example, to infer the element type of a (for e in list) loop.
     *
     * @param collectionType the type of the collection
     * @return the inferred component type
     */
public static ClassNode inferLoopElementType(final ClassNode collectionType) {
    ClassNode componentType = collectionType.getComponentType();
    if (componentType == null) {
        if (implementsInterfaceOrIsSubclassOf(collectionType, ITERABLE_TYPE)) {
            ClassNode intf = GenericsUtils.parameterizeType(collectionType, ITERABLE_TYPE);
            GenericsType[] genericsTypes = intf.getGenericsTypes();
            componentType = genericsTypes[0].getType();
        } else if (implementsInterfaceOrIsSubclassOf(collectionType, MAP_TYPE)) {
            // GROOVY-6240
            ClassNode intf = GenericsUtils.parameterizeType(collectionType, MAP_TYPE);
            GenericsType[] genericsTypes = intf.getGenericsTypes();
            componentType = MAP_ENTRY_TYPE.getPlainNodeReference();
            componentType.setGenericsTypes(genericsTypes);
        } else if (STRING_TYPE.equals(collectionType)) {
            componentType = ClassHelper.Character_TYPE;
        } else if (ENUMERATION_TYPE.equals(collectionType)) {
            // GROOVY-6123
            ClassNode intf = GenericsUtils.parameterizeType(collectionType, ENUMERATION_TYPE);
            GenericsType[] genericsTypes = intf.getGenericsTypes();
            componentType = genericsTypes[0].getType();
        } else {
            componentType = ClassHelper.OBJECT_TYPE;
        }
    }
    return componentType;
}
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 50 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)

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