private CollectionLiteralAnnotationTerm startCollection(Tree.Term t) { Unit unit = t.getUnit(); // Continue the visit to collect the elements ProducedType iteratedType = unit.getIteratedType(parameter().getType()); TypeDeclaration declaration = iteratedType.getDeclaration(); LiteralAnnotationTerm factory; if (unit.getStringDeclaration().equals(declaration)) { factory = StringLiteralAnnotationTerm.FACTORY; } else if (unit.getIntegerDeclaration().equals(declaration)) { factory = IntegerLiteralAnnotationTerm.FACTORY; } else if (unit.getCharacterDeclaration().equals(declaration)) { factory = CharacterLiteralAnnotationTerm.FACTORY; } else if (unit.getBooleanDeclaration().equals(declaration)) { factory = BooleanLiteralAnnotationTerm.FACTORY; } else if (unit.getFloatDeclaration().equals(declaration)) { factory = FloatLiteralAnnotationTerm.FACTORY; } else if (Decl.isEnumeratedTypeWithAnonCases(iteratedType)) { factory = ObjectLiteralAnnotationTerm.FACTORY; } else if (Decl.isAnnotationClass(declaration)) { t.addError( "compiler bug: iterables of annotation classes or annotation constructors not supported as literal " + (checkingDefaults ? "defaulted parameters" : "arguments")); return null; } else if (iteratedType.isSubtypeOf( ((TypeDeclaration) unit.getLanguageModuleDeclarationDeclaration("Declaration")) .getType())) { factory = DeclarationLiteralAnnotationTerm.FACTORY; } else { throw new RuntimeException(); } CollectionLiteralAnnotationTerm result = this.elements; this.elements = new CollectionLiteralAnnotationTerm(factory); return result; }
private List<ProducedType> getSupertypes(List<ProducedType> list) { if (isWellDefined() && Util.addToSupertypes(list, this)) { ProducedType extendedType = getExtendedType(); if (extendedType != null) { extendedType.getSupertypes(list); } for (ProducedType dst : getSatisfiedTypes()) { dst.getSupertypes(list); } ProducedType selfType = getSelfType(); if (selfType != null) { if (!(selfType.getDeclaration() instanceof TypeParameter)) { // TODO: is this really correct??? selfType.getSupertypes(list); } } List<ProducedType> caseTypes = getCaseTypes(); if (caseTypes != null /*&& !getDeclaration().getCaseTypes().isEmpty()*/) { for (ProducedType t : caseTypes) { List<ProducedType> candidates = t.getSupertypes(); for (ProducedType st : candidates) { boolean include = true; for (ProducedType ct : getDeclaration().getCaseTypes()) { if (!ct.isSubtypeOf(st)) { include = false; break; } } if (include) { Util.addToSupertypes(list, st); } } } } } return list; }
private ProducedType getCommonSupertype( final List<ProducedType> caseTypes, TypeDeclaration dec, final TypeDeclaration selfTypeToIgnore) { // now try to construct a common produced // type that is a common supertype by taking // the type args and unioning them List<ProducedType> args = new ArrayList<ProducedType>(); for (TypeParameter tp : dec.getTypeParameters()) { List<ProducedType> list2 = new ArrayList<ProducedType>(); ProducedType result; if (tp.isContravariant()) { for (ProducedType pt : caseTypes) { ProducedType st = pt.getSupertype(dec, selfTypeToIgnore); if (st == null) { return null; } addToIntersection(list2, st.getTypeArguments().get(tp)); } IntersectionType it = new IntersectionType(getDeclaration().getUnit()); it.setSatisfiedTypes(list2); result = it.canonicalize().getType(); } else { for (ProducedType pt : caseTypes) { ProducedType st = pt.getSupertype(dec, selfTypeToIgnore); if (st == null) { return null; } addToUnion(list2, st.getTypeArguments().get(tp)); } UnionType ut = new UnionType(getDeclaration().getUnit()); ut.setCaseTypes(list2); result = ut.getType(); } args.add(result); } // check that the unioned type args // satisfy the type constraints for (int i = 0; i < args.size(); i++) { TypeParameter tp = dec.getTypeParameters().get(i); for (ProducedType ub : tp.getSatisfiedTypes()) { if (!args.get(i).isSubtypeOf(ub)) { return null; } } } // recurse to the qualifying type ProducedType outerType; if (dec.isMember()) { TypeDeclaration outer = (TypeDeclaration) dec.getContainer(); List<ProducedType> list = new ArrayList<ProducedType>(); for (ProducedType pt : caseTypes) { ProducedType st = pt.getQualifyingType().getSupertype(outer, null); list.add(st); } outerType = getCommonSupertype(list, outer, null); } else { outerType = null; } // make the resulting type ProducedType candidateResult = dec.getProducedType(outerType, args); // check the the resulting type is *really* // a subtype (take variance into account) for (ProducedType pt : caseTypes) { if (!pt.isSubtypeOf(candidateResult)) { return null; } } return candidateResult; }
/** Search for the most-specialized supertype satisfying the given predicate. */ private ProducedType getSupertype( final Criteria c, List<ProducedType> list, final TypeDeclaration ignoringSelfType) { if (c.satisfies(getDeclaration())) { return qualifiedByDeclaringType(); } if (isWellDefined() && Util.addToSupertypes(list, this)) { // search for the most-specific supertype // for the given declaration ProducedType result = null; ProducedType extendedType = getInternalExtendedType(); if (extendedType != null) { ProducedType possibleResult = extendedType.getSupertype(c, list, ignoringSelfType); if (possibleResult != null) { result = possibleResult; } } for (ProducedType dst : getInternalSatisfiedTypes()) { ProducedType possibleResult = dst.getSupertype(c, list, ignoringSelfType); if (possibleResult != null && (result == null || possibleResult.isSubtypeOf(result, ignoringSelfType))) { result = possibleResult; } } if (!getDeclaration().equals(ignoringSelfType)) { ProducedType selfType = getInternalSelfType(); if (selfType != null) { ProducedType possibleResult = selfType.getSupertype(c, list, ignoringSelfType); if (possibleResult != null && (result == null || possibleResult.isSubtypeOf(result, ignoringSelfType))) { result = possibleResult; } } } final List<ProducedType> caseTypes = getInternalCaseTypes(); if (caseTypes != null && !caseTypes.isEmpty()) { // first find a common superclass or superinterface // declaration that satisfies the criteria, ignoring // type arguments for now Criteria c2 = new Criteria() { @Override public boolean satisfies(TypeDeclaration type) { if (c.satisfies(type)) { for (ProducedType ct : caseTypes) { if (ct.getSupertype(type, ignoringSelfType) == null) { return false; } } return true; } else { return false; } } }; ProducedType stc = caseTypes.get(0).getSupertype(c2, list, ignoringSelfType); if (stc != null) { // we found the declaration, now try to construct a // produced type that is a true common supertype ProducedType candidateResult = getCommonSupertype(caseTypes, stc.getDeclaration(), ignoringSelfType); if (candidateResult != null && (result == null || candidateResult.isSubtypeOf(result, ignoringSelfType))) { result = candidateResult; } } } return result; } else { return null; } }
/** Is this type a subtype of the given type? Ignore a certain self type constraint. */ public boolean isSubtypeOf(ProducedType type, TypeDeclaration selfTypeToIgnore) { if (getDeclaration() instanceof BottomType) { return true; } else if (type.getDeclaration() instanceof BottomType) { return false; } else if (getDeclaration() instanceof UnionType) { for (ProducedType ct : getInternalCaseTypes()) { if (ct == null || !ct.isSubtypeOf(type, selfTypeToIgnore)) { return false; } } return true; } else if (type.getDeclaration() instanceof UnionType) { for (ProducedType ct : type.getInternalCaseTypes()) { if (ct != null && isSubtypeOf(ct, selfTypeToIgnore)) { return true; } } return false; } else if (type.getDeclaration() instanceof IntersectionType) { for (ProducedType ct : type.getInternalSatisfiedTypes()) { if (ct != null && !isSubtypeOf(ct, selfTypeToIgnore)) { return false; } } return true; } else if (getDeclaration() instanceof IntersectionType) { for (ProducedType ct : getInternalSatisfiedTypes()) { if (ct == null || ct.isSubtypeOf(type, selfTypeToIgnore)) { return true; } } return false; } else { ProducedType st = getSupertype(type.getDeclaration(), selfTypeToIgnore); if (st == null) { return false; } else { ProducedType stqt = st.getQualifyingType(); ProducedType tqt = type.getQualifyingType(); if (stqt == null) { if (tqt != null) { // probably extraneous! return false; } } else { if (tqt == null) { // probably extraneous! return false; } else { // note that the qualifying type of the // given type may be an invariant subtype // of the type that declares the member // type, as long as it doesn't refine the // member type TypeDeclaration totd = (TypeDeclaration) type.getDeclaration().getContainer(); ProducedType tqts = tqt.getSupertype(totd); if (!stqt.isSubtypeOf(tqts)) { return false; } } } for (TypeParameter p : type.getDeclaration().getTypeParameters()) { ProducedType arg = st.getTypeArguments().get(p); ProducedType otherArg = type.getTypeArguments().get(p); if (arg == null || otherArg == null) { /*throw new RuntimeException("Missing type argument for type parameter: " + p.getName() + " of " + type.getDeclaration().getName());*/ return false; } else if (p.isCovariant()) { if (!arg.isSubtypeOf(otherArg)) { return false; } } else if (p.isContravariant()) { if (!otherArg.isSubtypeOf(arg)) { return false; } } else { if (!arg.isExactly(otherArg)) { return false; } } } return true; } } }
/** Is this type a supertype of the given type? */ public boolean isSupertypeOf(ProducedType type) { return type.isSubtypeOf(this); }