예제 #1
0
 void addTypeToIntersection(
     ProducedType ct, Map<TypeParameter, ProducedType> substitutions, List<ProducedType> types) {
   if (ct == null) {
     types.add(null);
   } else {
     addToIntersection(types, substitute(ct, substitutions));
   }
 }
예제 #2
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;
 }