@Override
 public ProducedType getReference() {
   ProducedType pt = new ProducedType();
   if (isMember()) {
     pt.setQualifyingType(((ClassOrInterface) getContainer()).getType());
   }
   pt.setDeclaration(this);
   pt.setTypeArguments(
       getTypeArgumentMap(this, pt.getQualifyingType(), Collections.<ProducedType>emptyList()));
   return pt;
 }
Beispiel #2
0
 private ProducedType substitutedType(
     Declaration dec, ProducedType pt, Map<TypeParameter, ProducedType> substitutions) {
   ProducedType type = new ProducedType();
   type.setDeclaration(dec);
   ProducedType qt = pt.getQualifyingType();
   if (qt != null) {
     type.setQualifyingType(substitute(qt, substitutions));
   }
   type.setTypeArguments(substitutedTypeArguments(pt, substitutions));
   return type;
 }
  @Test
  public void testPackageQualified() {
    ProducedType type = new TypeParser(MockLoader.instance, mockUnit).decodeType("unknown.b", null);
    Assert.assertNotNull(type);
    TypeDeclaration declaration = type.getDeclaration();
    Assert.assertNotNull(declaration);
    Assert.assertTrue(declaration instanceof Class);
    Assert.assertEquals("unknown.b", declaration.getName());

    Assert.assertNull(type.getQualifyingType());
  }
  @Test
  public void testQualifiedAndParameterised() {
    ProducedType type =
        new TypeParser(MockLoader.instance, mockUnit).decodeType("t2<a,b>.t2<c,d>", null);
    Assert.assertNotNull(type);
    TypeDeclaration declaration = type.getDeclaration();
    Assert.assertNotNull(declaration);
    Assert.assertTrue(declaration instanceof Class);
    Assert.assertEquals("t2.t2", declaration.getName());
    Assert.assertEquals(2, type.getTypeArgumentList().size());

    // c
    ProducedType c = type.getTypeArgumentList().get(0);
    Assert.assertEquals("c", c.getDeclaration().getName());
    Assert.assertTrue(c.getDeclaration() instanceof Class);

    // d
    ProducedType d = type.getTypeArgumentList().get(1);
    Assert.assertEquals("d", d.getDeclaration().getName());
    Assert.assertTrue(d.getDeclaration() instanceof Class);

    ProducedType qualifyingType = type.getQualifyingType();
    Assert.assertNotNull(qualifyingType);
    TypeDeclaration qualifyingDeclaration = qualifyingType.getDeclaration();
    Assert.assertNotNull(qualifyingDeclaration);
    Assert.assertTrue(qualifyingDeclaration instanceof Class);
    Assert.assertEquals("t2", qualifyingDeclaration.getName());
    Assert.assertEquals(2, qualifyingType.getTypeArgumentList().size());

    // a
    ProducedType a = qualifyingType.getTypeArgumentList().get(0);
    Assert.assertEquals("a", a.getDeclaration().getName());
    Assert.assertTrue(a.getDeclaration() instanceof Class);

    // b
    ProducedType b = qualifyingType.getTypeArgumentList().get(1);
    Assert.assertEquals("b", b.getDeclaration().getName());
    Assert.assertTrue(b.getDeclaration() instanceof Class);
  }
Beispiel #5
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 #6
0
 /** Is this type exactly the same type as the given type? */
 public boolean isExactly(ProducedType type) {
   if (getDeclaration() instanceof BottomType) {
     return type.getDeclaration() instanceof BottomType;
   } else if (getDeclaration() instanceof UnionType) {
     List<ProducedType> cases = getCaseTypes();
     if (type.getDeclaration() instanceof UnionType) {
       List<ProducedType> otherCases = type.getCaseTypes();
       if (cases.size() != otherCases.size()) {
         return false;
       } else {
         for (ProducedType c : cases) {
           boolean found = false;
           for (ProducedType oc : otherCases) {
             if (c.isExactly(oc)) {
               found = true;
               break;
             }
           }
           if (!found) {
             return false;
           }
         }
         return true;
       }
     } else if (cases.size() == 1) {
       ProducedType st = cases.get(0);
       return st.isExactly(type);
     } else {
       return false;
     }
   } else if (getDeclaration() instanceof IntersectionType) {
     List<ProducedType> types = getSatisfiedTypes();
     if (type.getDeclaration() instanceof IntersectionType) {
       List<ProducedType> otherTypes = type.getSatisfiedTypes();
       if (types.size() != otherTypes.size()) {
         return false;
       } else {
         for (ProducedType c : types) {
           boolean found = false;
           for (ProducedType oc : otherTypes) {
             if (c.isExactly(oc)) {
               found = true;
               break;
             }
           }
           if (!found) {
             return false;
           }
         }
         return true;
       }
     } else if (types.size() == 1) {
       ProducedType st = types.get(0);
       return st.isExactly(type);
     } else {
       return false;
     }
   } else if (type.getDeclaration() instanceof UnionType) {
     List<ProducedType> otherCases = type.getCaseTypes();
     if (otherCases.size() == 1) {
       ProducedType st = otherCases.get(0);
       return this.isExactly(st);
     } else {
       return false;
     }
   } else if (type.getDeclaration() instanceof IntersectionType) {
     List<ProducedType> otherTypes = type.getSatisfiedTypes();
     if (otherTypes.size() == 1) {
       ProducedType st = otherTypes.get(0);
       return this.isExactly(st);
     } else {
       return false;
     }
   } else {
     if (!type.getDeclaration().equals(getDeclaration())) {
       return false;
     } else {
       ProducedType qt = getQualifyingType();
       ProducedType tqt = type.getQualifyingType();
       if (qt == null) {
         if (tqt != null) {
           return false;
         }
       } else {
         if (tqt == null) {
           return false;
         } else {
           TypeDeclaration totd = (TypeDeclaration) type.getDeclaration().getContainer();
           ProducedType tqts = tqt.getSupertype(totd);
           TypeDeclaration otd = (TypeDeclaration) getDeclaration().getContainer();
           ProducedType qts = qt.getSupertype(otd);
           if (!qts.isExactly(tqts)) {
             return false;
           }
         }
       }
       for (TypeParameter p : getDeclaration().getTypeParameters()) {
         ProducedType arg = getTypeArguments().get(p);
         ProducedType otherArg = type.getTypeArguments().get(p);
         if (arg == null || otherArg == null) {
           return false;
           /*throw new RuntimeException(
           "Missing type argument for: " +
                   p.getName() + " of " +
                   getDeclaration().getName());*/
         } else if (!arg.isExactly(otherArg)) {
           return false;
         }
       }
       return true;
     }
   }
 }
Beispiel #7
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;
     }
   }
 }