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;
}
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;
}
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;
}
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());
}
}
}
use of org.codehaus.groovy.ast.GenericsType in project groovy by apache.
the class StaticTypeCheckingSupport method fullyResolve.
/**
* Given a generics type representing SomeClass<T,V> 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;
}
Aggregations