private boolean argsEquivalent(ParameterizedType ancestor) { for (int i = 0; i < ancestor.typeArguments().size(); i++) { Type arg1 = (Type) ancestor.typeArguments().get(i); Type arg2 = (Type) typeArguments().get(i); IntersectionType cap1 = (IntersectionType) ancestor.typeVariables().get(i); IntersectionType cap2 = (IntersectionType) baseType().typeVariables().get(i); // if both are AnySubType then arg2 bound must be subtype // of arg1 bound if (arg1 instanceof AnySubType) { if (arg2 instanceof AnySubType) { if (!typeSystem().equals(((AnySubType) arg2).bound(), ((AnySubType) arg1).bound())) return false; } else if (arg2 instanceof AnySuperType) { if (!typeSystem().equals(((AnySubType) arg1).bound(), ((AnySuperType) arg2).bound())) return false; } else if (arg2 instanceof IntersectionType) { // need to break out here or will recurse for ever if (((IntersectionType) arg2) .name() .equals(((IntersectionType) ((AnySubType) arg1).bound()).name())) return true; } // if only ancestor(arg1) is AnySubType then arg2 is not // wildcard must be subtype of bound of arg1 else { if (!typeSystem().equals(arg2, arg1)) return false; } } // if both are AnySuperType then arg1 bound must be a subtype // of arg2 bound else if (arg1 instanceof AnySuperType) { if (arg2 instanceof AnySuperType) { if (!typeSystem().equals(((AnySuperType) arg1).bound(), ((AnySuperType) arg2).bound())) return false; } // if only arg1 instanceof AnySuperType then arg1 bounds // must be a subtype of arg2 else { if (!typeSystem().equals(arg1, arg2)) return false; } } else if (arg1 instanceof AnyType) { if (arg2 instanceof AnyType) { if (!typeSystem().equals(((AnyType) arg1).upperBound(), ((AnyType) arg2).upperBound())) return false; } else { if (!typeSystem().equals(arg1, arg2)) return false; } } else if (arg1 instanceof ParameterizedType && arg2 instanceof ParameterizedType) { // if (arg1.equals(arg2)) return true; if (!typeSystem().equals(arg1, arg2)) return false; } else if (arg1 instanceof IntersectionType && arg2 instanceof IntersectionType) { if (!typeSystem().equals(arg1, arg2) && !((JL5TypeSystem) typeSystem()).isEquivalent(arg1, arg2)) return false; } else { if (!typeSystem().equals(arg1, arg2)) return false; } } return true; }
public Type convertToInferred(List typeVars, List inferredTypes) { List newBounds = new ArrayList(); for (Iterator it = typeArguments().iterator(); it.hasNext(); ) { Type next = (Type) it.next(); if (next instanceof IntersectionType) { newBounds.add(inferredTypes.get(typeVars.indexOf(next))); } else if (next instanceof ParameterizedType) { newBounds.add(((ParameterizedType) next).convertToInferred(typeVars, inferredTypes)); } /*else if (next instanceof AnySubType){ newBounds.add(((AnySubType)next).convertToInferred(typeVars, inferredTypes)); }*/ else { newBounds.add(next); } } ParameterizedType converted = ((JL5TypeSystem) typeSystem()).parameterizedType(this.baseType()); converted.typeArguments(newBounds); return converted; }