use of org.codehaus.groovy.ast.ClassNode in project groovy by apache.
the class GenericsUtils method extractSuperClassGenerics.
private static void extractSuperClassGenerics(GenericsType[] usage, GenericsType[] declaration, Map<String, ClassNode> spec) {
// if declaration does not provide generics, there is no connection to make
if (usage == null || declaration == null || declaration.length == 0)
return;
if (usage.length != declaration.length)
return;
// both have generics
for (int i = 0; i < usage.length; i++) {
GenericsType ui = usage[i];
GenericsType di = declaration[i];
if (di.isPlaceholder()) {
spec.put(di.getName(), ui.getType());
} else if (di.isWildcard()) {
if (ui.isWildcard()) {
extractSuperClassGenerics(ui.getLowerBound(), di.getLowerBound(), spec);
extractSuperClassGenerics(ui.getUpperBounds(), di.getUpperBounds(), spec);
} else {
ClassNode cu = ui.getType();
extractSuperClassGenerics(cu, di.getLowerBound(), spec);
ClassNode[] upperBounds = di.getUpperBounds();
if (upperBounds != null) {
for (ClassNode cn : upperBounds) {
extractSuperClassGenerics(cu, cn, spec);
}
}
}
} else {
extractSuperClassGenerics(ui.getType(), di.getType(), spec);
}
}
}
use of org.codehaus.groovy.ast.ClassNode in project groovy by apache.
the class WideningCategories method buildTypeWithInterfaces.
/**
* Given two class nodes supposedly at the upper common level, returns a class node which is able to represent
* their lowest upper bound.
* @param baseType1
* @param baseType2
* @param interfaces interfaces both class nodes share, which their lowest common super class do not implement.
* @return the class node representing the lowest upper bound
*/
private static ClassNode buildTypeWithInterfaces(ClassNode baseType1, ClassNode baseType2, Collection<ClassNode> interfaces) {
boolean noInterface = interfaces.isEmpty();
if (noInterface) {
if (baseType1.equals(baseType2))
return baseType1;
if (baseType1.isDerivedFrom(baseType2))
return baseType2;
if (baseType2.isDerivedFrom(baseType1))
return baseType1;
}
if (OBJECT_TYPE.equals(baseType1) && OBJECT_TYPE.equals(baseType2) && interfaces.size() == 1) {
if (interfaces instanceof List) {
return ((List<ClassNode>) interfaces).get(0);
}
return interfaces.iterator().next();
}
LowestUpperBoundClassNode type;
ClassNode superClass;
String name;
if (baseType1.equals(baseType2)) {
if (OBJECT_TYPE.equals(baseType1)) {
superClass = baseType1;
name = "Virtual$Object";
} else {
superClass = baseType1;
name = "Virtual$" + baseType1.getName();
}
} else {
superClass = OBJECT_TYPE;
if (baseType1.isDerivedFrom(baseType2)) {
superClass = baseType2;
} else if (baseType2.isDerivedFrom(baseType1)) {
superClass = baseType1;
}
name = "CommonAssignOf$" + baseType1.getName() + "$" + baseType2.getName();
}
Iterator<ClassNode> itcn = interfaces.iterator();
while (itcn.hasNext()) {
ClassNode next = itcn.next();
if (superClass.isDerivedFrom(next) || superClass.implementsInterface(next)) {
itcn.remove();
}
}
ClassNode[] interfaceArray = interfaces.toArray(new ClassNode[interfaces.size()]);
Arrays.sort(interfaceArray, INTERFACE_CLASSNODE_COMPARATOR);
type = new LowestUpperBoundClassNode(name, superClass, interfaceArray);
return type;
}
use of org.codehaus.groovy.ast.ClassNode in project groovy by apache.
the class WideningCategories method lowestUpperBound.
/**
* Given two class nodes, returns the first common supertype, or the class itself
* if there are equal. For example, Double and Float would return Number, while
* Set and String would return Object.
*
* This method is not guaranteed to return a class node which corresponds to a
* real type. For example, if two types have more than one interface in common
* and are not in the same hierarchy branch, then the returned type will be a
* virtual type implementing all those interfaces.
*
* Calls to this method are supposed to be made with resolved generics. This means
* that you can have wildcards, but no placeholder.
*
* @param a first class node
* @param b second class node
* @return first common supertype
*/
public static ClassNode lowestUpperBound(ClassNode a, ClassNode b) {
ClassNode lub = lowestUpperBound(a, b, null, null);
if (lub == null || !lub.isUsingGenerics())
return lub;
if (lub instanceof LowestUpperBoundClassNode) {
// no parent super class representing both types could be found
// or both class nodes implement common interfaces which may have
// been parameterized differently.
// We must create a classnode for which the "superclass" is potentially parameterized
// plus the interfaces
ClassNode superClass = lub.getSuperClass();
ClassNode psc = superClass.isUsingGenerics() ? parameterizeLowestUpperBound(superClass, a, b, lub) : superClass;
ClassNode[] interfaces = lub.getInterfaces();
ClassNode[] pinterfaces = new ClassNode[interfaces.length];
for (int i = 0, interfacesLength = interfaces.length; i < interfacesLength; i++) {
final ClassNode icn = interfaces[i];
if (icn.isUsingGenerics()) {
pinterfaces[i] = parameterizeLowestUpperBound(icn, a, b, lub);
} else {
pinterfaces[i] = icn;
}
}
return new LowestUpperBoundClassNode(((LowestUpperBoundClassNode) lub).name, psc, pinterfaces);
} else {
return parameterizeLowestUpperBound(lub, a, b, lub);
}
}
use of org.codehaus.groovy.ast.ClassNode in project groovy by apache.
the class TypeSignatureParser method createWildcard.
private static GenericsType createWildcard(ClassNode[] upper, ClassNode lower) {
ClassNode base = ClassHelper.makeWithoutCaching("?");
base.setRedirect(ClassHelper.OBJECT_TYPE);
GenericsType t = new GenericsType(base, upper, lower);
t.setWildcard(true);
return t;
}
use of org.codehaus.groovy.ast.ClassNode in project groovy by apache.
the class ArrayExpression method makeArray.
private static ClassNode makeArray(ClassNode base, List<Expression> sizeExpression) {
ClassNode ret = base.makeArray();
if (sizeExpression == null)
return ret;
int size = sizeExpression.size();
for (int i = 1; i < size; i++) {
ret = ret.makeArray();
}
return ret;
}
Aggregations