use of org.codehaus.groovy.ast.GenericsType in project groovy by apache.
the class StaticTypeCheckingVisitor method makeOwnerList.
/**
* Given an object expression (a receiver expression), generate the list of potential receiver types.
* @param objectExpression the receiver expression
* @return the list of types the receiver may be
*/
protected List<Receiver<String>> makeOwnerList(final Expression objectExpression) {
final ClassNode receiver = getType(objectExpression);
List<Receiver<String>> owners = new LinkedList<Receiver<String>>();
owners.add(Receiver.<String>make(receiver));
if (isClassClassNodeWrappingConcreteType(receiver)) {
GenericsType clazzGT = receiver.getGenericsTypes()[0];
owners.add(0, Receiver.<String>make(clazzGT.getType()));
}
if (receiver.isInterface()) {
// GROOVY-xxxx
owners.add(Receiver.<String>make(OBJECT_TYPE));
}
addSelfTypes(receiver, owners);
if (!typeCheckingContext.temporaryIfBranchTypeInformation.empty()) {
List<ClassNode> potentialReceiverType = getTemporaryTypesForExpression(objectExpression);
if (potentialReceiverType != null) {
for (ClassNode node : potentialReceiverType) {
owners.add(Receiver.<String>make(node));
}
}
}
if (typeCheckingContext.lastImplicitItType != null && objectExpression instanceof VariableExpression && ((VariableExpression) objectExpression).getName().equals("it")) {
owners.add(Receiver.<String>make(typeCheckingContext.lastImplicitItType));
}
return owners;
}
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;
}
Aggregations