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;
}
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;
}
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;
}
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;
}
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;
}
Aggregations