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;
 }
Beispiel #2
0
 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;
 }
Beispiel #3
0
 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;
 }
Beispiel #4
0
 /** 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;
   }
 }
Beispiel #5
0
 /** 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;
     }
   }
 }
Beispiel #6
0
 /** Is this type a supertype of the given type? */
 public boolean isSupertypeOf(ProducedType type) {
   return type.isSubtypeOf(this);
 }