24 */ |
24 */ |
25 |
25 |
26 package com.sun.tools.javac.code; |
26 package com.sun.tools.javac.code; |
27 |
27 |
28 import java.lang.ref.SoftReference; |
28 import java.lang.ref.SoftReference; |
29 import java.util.Comparator; |
|
30 import java.util.HashSet; |
29 import java.util.HashSet; |
31 import java.util.HashMap; |
30 import java.util.HashMap; |
32 import java.util.Locale; |
31 import java.util.Locale; |
33 import java.util.Map; |
32 import java.util.Map; |
34 import java.util.Set; |
33 import java.util.Set; |
35 import java.util.WeakHashMap; |
34 import java.util.WeakHashMap; |
36 |
|
37 import javax.lang.model.type.TypeKind; |
|
38 |
35 |
39 import com.sun.tools.javac.code.Attribute.RetentionPolicy; |
36 import com.sun.tools.javac.code.Attribute.RetentionPolicy; |
40 import com.sun.tools.javac.code.Lint.LintCategory; |
37 import com.sun.tools.javac.code.Lint.LintCategory; |
41 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound; |
38 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound; |
42 import com.sun.tools.javac.comp.Check; |
39 import com.sun.tools.javac.comp.Check; |
202 List<Type> args = t.allparams(); |
199 List<Type> args = t.allparams(); |
203 while (parms.nonEmpty()) { |
200 while (parms.nonEmpty()) { |
204 WildcardType unb = new WildcardType(syms.objectType, |
201 WildcardType unb = new WildcardType(syms.objectType, |
205 BoundKind.UNBOUND, |
202 BoundKind.UNBOUND, |
206 syms.boundClass, |
203 syms.boundClass, |
207 (TypeVar)parms.head); |
204 (TypeVar)parms.head.unannotatedType()); |
208 if (!containsType(args.head, unb)) |
205 if (!containsType(args.head, unb)) |
209 return false; |
206 return false; |
210 parms = parms.tail; |
207 parms = parms.tail; |
211 args = args.tail; |
208 args = args.tail; |
212 } |
209 } |
266 } else { |
263 } else { |
267 // Unbound type arguments default to ? |
264 // Unbound type arguments default to ? |
268 List<Type> opens = openVars.toList(); |
265 List<Type> opens = openVars.toList(); |
269 ListBuffer<Type> qs = new ListBuffer<Type>(); |
266 ListBuffer<Type> qs = new ListBuffer<Type>(); |
270 for (List<Type> iter = opens; iter.nonEmpty(); iter = iter.tail) { |
267 for (List<Type> iter = opens; iter.nonEmpty(); iter = iter.tail) { |
271 qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head)); |
268 qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head.unannotatedType())); |
272 } |
269 } |
273 res = subst(res, opens, qs.toList()); |
270 res = subst(res, opens, qs.toList()); |
274 } |
271 } |
275 } |
272 } |
276 return res; |
273 return res; |
579 List<Type> actualTypeargs = site.getTypeArguments(); |
576 List<Type> actualTypeargs = site.getTypeArguments(); |
580 List<Type> capturedTypeargs = capturedSite.getTypeArguments(); |
577 List<Type> capturedTypeargs = capturedSite.getTypeArguments(); |
581 //simply replace the wildcards with its bound |
578 //simply replace the wildcards with its bound |
582 for (Type t : formalInterface.getTypeArguments()) { |
579 for (Type t : formalInterface.getTypeArguments()) { |
583 if (actualTypeargs.head.hasTag(WILDCARD)) { |
580 if (actualTypeargs.head.hasTag(WILDCARD)) { |
584 WildcardType wt = (WildcardType)actualTypeargs.head; |
581 WildcardType wt = (WildcardType)actualTypeargs.head.unannotatedType(); |
585 Type bound; |
582 Type bound; |
586 switch (wt.kind) { |
583 switch (wt.kind) { |
587 case EXTENDS: |
584 case EXTENDS: |
588 case UNBOUND: |
585 case UNBOUND: |
589 CapturedType capVar = (CapturedType)capturedTypeargs.head; |
586 CapturedType capVar = (CapturedType)capturedTypeargs.head.unannotatedType(); |
590 //use declared bound if it doesn't depend on formal type-args |
587 //use declared bound if it doesn't depend on formal type-args |
591 bound = capVar.bound.containsAny(capturedSite.getTypeArguments()) ? |
588 bound = capVar.bound.containsAny(capturedSite.getTypeArguments()) ? |
592 wt.type : capVar.bound; |
589 wt.type : capVar.bound; |
593 break; |
590 break; |
594 default: |
591 default: |
962 public boolean isSameType(Type t, Type s, boolean strict) { |
959 public boolean isSameType(Type t, Type s, boolean strict) { |
963 return strict ? |
960 return strict ? |
964 isSameTypeStrict.visit(t, s) : |
961 isSameTypeStrict.visit(t, s) : |
965 isSameTypeLoose.visit(t, s); |
962 isSameTypeLoose.visit(t, s); |
966 } |
963 } |
|
964 public boolean isSameAnnotatedType(Type t, Type s) { |
|
965 return isSameAnnotatedType.visit(t, s); |
|
966 } |
967 // where |
967 // where |
968 abstract class SameTypeVisitor extends TypeRelation { |
968 abstract class SameTypeVisitor extends TypeRelation { |
969 |
969 |
970 public Boolean visitType(Type t, Type s) { |
970 public Boolean visitType(Type t, Type s) { |
971 if (t == s) |
971 if (t == s) |
980 return t.tag == s.tag; |
980 return t.tag == s.tag; |
981 case TYPEVAR: { |
981 case TYPEVAR: { |
982 if (s.tag == TYPEVAR) { |
982 if (s.tag == TYPEVAR) { |
983 //type-substitution does not preserve type-var types |
983 //type-substitution does not preserve type-var types |
984 //check that type var symbols and bounds are indeed the same |
984 //check that type var symbols and bounds are indeed the same |
985 return sameTypeVars((TypeVar)t, (TypeVar)s); |
985 return sameTypeVars((TypeVar)t.unannotatedType(), (TypeVar)s.unannotatedType()); |
986 } |
986 } |
987 else { |
987 else { |
988 //special case for s == ? super X, where upper(s) = u |
988 //special case for s == ? super X, where upper(s) = u |
989 //check that u == t, where u has been set by Type.withTypeVar |
989 //check that u == t, where u has been set by Type.withTypeVar |
990 return s.isSuperBound() && |
990 return s.isSuperBound() && |
1094 |
1094 |
1095 /** |
1095 /** |
1096 * Standard type-equality relation - type variables are considered |
1096 * Standard type-equality relation - type variables are considered |
1097 * equals if they share the same type symbol. |
1097 * equals if they share the same type symbol. |
1098 */ |
1098 */ |
1099 TypeRelation isSameTypeLoose = new SameTypeVisitor() { |
1099 TypeRelation isSameTypeLoose = new LooseSameTypeVisitor(); |
|
1100 |
|
1101 private class LooseSameTypeVisitor extends SameTypeVisitor { |
1100 @Override |
1102 @Override |
1101 boolean sameTypeVars(TypeVar tv1, TypeVar tv2) { |
1103 boolean sameTypeVars(TypeVar tv1, TypeVar tv2) { |
1102 return tv1.tsym == tv2.tsym && visit(tv1.getUpperBound(), tv2.getUpperBound()); |
1104 return tv1.tsym == tv2.tsym && visit(tv1.getUpperBound(), tv2.getUpperBound()); |
1103 } |
1105 } |
1104 @Override |
1106 @Override |
1124 @Override |
1126 @Override |
1125 public Boolean visitWildcardType(WildcardType t, Type s) { |
1127 public Boolean visitWildcardType(WildcardType t, Type s) { |
1126 if (!s.hasTag(WILDCARD)) { |
1128 if (!s.hasTag(WILDCARD)) { |
1127 return false; |
1129 return false; |
1128 } else { |
1130 } else { |
1129 WildcardType t2 = (WildcardType)s; |
1131 WildcardType t2 = (WildcardType)s.unannotatedType(); |
1130 return t.kind == t2.kind && |
1132 return t.kind == t2.kind && |
1131 isSameType(t.type, t2.type, true); |
1133 isSameType(t.type, t2.type, true); |
1132 } |
1134 } |
|
1135 } |
|
1136 }; |
|
1137 |
|
1138 /** |
|
1139 * A version of LooseSameTypeVisitor that takes AnnotatedTypes |
|
1140 * into account. |
|
1141 */ |
|
1142 TypeRelation isSameAnnotatedType = new LooseSameTypeVisitor() { |
|
1143 @Override |
|
1144 public Boolean visitAnnotatedType(AnnotatedType t, Type s) { |
|
1145 if (!s.isAnnotated()) |
|
1146 return false; |
|
1147 if (!t.getAnnotationMirrors().containsAll(s.getAnnotationMirrors())) |
|
1148 return false; |
|
1149 if (!s.getAnnotationMirrors().containsAll(t.getAnnotationMirrors())) |
|
1150 return false; |
|
1151 return visit(t.underlyingType, s); |
1133 } |
1152 } |
1134 }; |
1153 }; |
1135 // </editor-fold> |
1154 // </editor-fold> |
1136 |
1155 |
1137 // <editor-fold defaultstate="collapsed" desc="Contains Type"> |
1156 // <editor-fold defaultstate="collapsed" desc="Contains Type"> |
1138 public boolean containedBy(Type t, Type s) { |
1157 public boolean containedBy(Type t, Type s) { |
1139 switch (t.tag) { |
1158 switch (t.tag) { |
1140 case UNDETVAR: |
1159 case UNDETVAR: |
1141 if (s.tag == WILDCARD) { |
1160 if (s.tag == WILDCARD) { |
1142 UndetVar undetvar = (UndetVar)t; |
1161 UndetVar undetvar = (UndetVar)t; |
1143 WildcardType wt = (WildcardType)s; |
1162 WildcardType wt = (WildcardType)s.unannotatedType(); |
1144 switch(wt.kind) { |
1163 switch(wt.kind) { |
1145 case UNBOUND: //similar to ? extends Object |
1164 case UNBOUND: //similar to ? extends Object |
1146 case EXTENDS: { |
1165 case EXTENDS: { |
1147 Type bound = upperBound(s); |
1166 Type bound = upperBound(s); |
1148 undetvar.addBound(InferenceBound.UPPER, bound, this); |
1167 undetvar.addBound(InferenceBound.UPPER, bound, this); |
1205 // where |
1224 // where |
1206 private TypeRelation containsType = new TypeRelation() { |
1225 private TypeRelation containsType = new TypeRelation() { |
1207 |
1226 |
1208 private Type U(Type t) { |
1227 private Type U(Type t) { |
1209 while (t.tag == WILDCARD) { |
1228 while (t.tag == WILDCARD) { |
1210 WildcardType w = (WildcardType)t; |
1229 WildcardType w = (WildcardType)t.unannotatedType(); |
1211 if (w.isSuperBound()) |
1230 if (w.isSuperBound()) |
1212 return w.bound == null ? syms.objectType : w.bound.bound; |
1231 return w.bound == null ? syms.objectType : w.bound.bound; |
1213 else |
1232 else |
1214 t = w.type; |
1233 t = w.type; |
1215 } |
1234 } |
1216 return t; |
1235 return t; |
1217 } |
1236 } |
1218 |
1237 |
1219 private Type L(Type t) { |
1238 private Type L(Type t) { |
1220 while (t.tag == WILDCARD) { |
1239 while (t.tag == WILDCARD) { |
1221 WildcardType w = (WildcardType)t; |
1240 WildcardType w = (WildcardType)t.unannotatedType(); |
1222 if (w.isExtendsBound()) |
1241 if (w.isExtendsBound()) |
1223 return syms.botType; |
1242 return syms.botType; |
1224 else |
1243 else |
1225 t = w.type; |
1244 t = w.type; |
1226 } |
1245 } |
1274 return true; |
1293 return true; |
1275 } |
1294 } |
1276 }; |
1295 }; |
1277 |
1296 |
1278 public boolean isCaptureOf(Type s, WildcardType t) { |
1297 public boolean isCaptureOf(Type s, WildcardType t) { |
1279 if (s.tag != TYPEVAR || !((TypeVar)s).isCaptured()) |
1298 if (s.tag != TYPEVAR || !((TypeVar)s.unannotatedType()).isCaptured()) |
1280 return false; |
1299 return false; |
1281 return isSameWildcard(t, ((CapturedType)s).wildcard); |
1300 return isSameWildcard(t, ((CapturedType)s.unannotatedType()).wildcard); |
1282 } |
1301 } |
1283 |
1302 |
1284 public boolean isSameWildcard(WildcardType t, Type s) { |
1303 public boolean isSameWildcard(WildcardType t, Type s) { |
1285 if (s.tag != WILDCARD) |
1304 if (s.tag != WILDCARD) |
1286 return false; |
1305 return false; |
1287 WildcardType w = (WildcardType)s; |
1306 WildcardType w = (WildcardType)s.unannotatedType(); |
1288 return w.kind == t.kind && w.type == t.type; |
1307 return w.kind == t.kind && w.type == t.type; |
1289 } |
1308 } |
1290 |
1309 |
1291 public boolean containsTypeEquivalent(List<Type> ts, List<Type> ss) { |
1310 public boolean containsTypeEquivalent(List<Type> ts, List<Type> ss) { |
1292 while (ts.nonEmpty() && ss.nonEmpty() |
1311 while (ts.nonEmpty() && ss.nonEmpty() |
1371 } |
1390 } |
1372 } |
1391 } |
1373 |
1392 |
1374 if (t.isCompound() || s.isCompound()) { |
1393 if (t.isCompound() || s.isCompound()) { |
1375 return !t.isCompound() ? |
1394 return !t.isCompound() ? |
1376 visitIntersectionType((IntersectionClassType)s, t, true) : |
1395 visitIntersectionType((IntersectionClassType)s.unannotatedType(), t, true) : |
1377 visitIntersectionType((IntersectionClassType)t, s, false); |
1396 visitIntersectionType((IntersectionClassType)t.unannotatedType(), s, false); |
1378 } |
1397 } |
1379 |
1398 |
1380 if (s.tag == CLASS || s.tag == ARRAY) { |
1399 if (s.tag == CLASS || s.tag == ARRAY) { |
1381 boolean upcast; |
1400 boolean upcast; |
1382 if ((upcast = isSubtype(erasure(t), erasure(s))) |
1401 if ((upcast = isSubtype(erasure(t), erasure(s))) |
3068 s.append('<'); |
3087 s.append('<'); |
3069 boolean first = true; |
3088 boolean first = true; |
3070 for (Type t : tvars) { |
3089 for (Type t : tvars) { |
3071 if (!first) s.append(", "); |
3090 if (!first) s.append(", "); |
3072 first = false; |
3091 first = false; |
3073 appendTyparamString(((TypeVar)t), s); |
3092 appendTyparamString(((TypeVar)t.unannotatedType()), s); |
3074 } |
3093 } |
3075 s.append('>'); |
3094 s.append('>'); |
3076 return s.toString(); |
3095 return s.toString(); |
3077 } |
3096 } |
3078 private void appendTyparamString(TypeVar t, StringBuilder buf) { |
3097 private void appendTyparamString(TypeVar t, StringBuilder buf) { |
3708 while (!currentA.isEmpty() && |
3727 while (!currentA.isEmpty() && |
3709 !currentT.isEmpty() && |
3728 !currentT.isEmpty() && |
3710 !currentS.isEmpty()) { |
3729 !currentS.isEmpty()) { |
3711 if (currentS.head != currentT.head) { |
3730 if (currentS.head != currentT.head) { |
3712 captured = true; |
3731 captured = true; |
3713 WildcardType Ti = (WildcardType)currentT.head; |
3732 WildcardType Ti = (WildcardType)currentT.head.unannotatedType(); |
3714 Type Ui = currentA.head.getUpperBound(); |
3733 Type Ui = currentA.head.getUpperBound(); |
3715 CapturedType Si = (CapturedType)currentS.head; |
3734 CapturedType Si = (CapturedType)currentS.head.unannotatedType(); |
3716 if (Ui == null) |
3735 if (Ui == null) |
3717 Ui = syms.objectType; |
3736 Ui = syms.objectType; |
3718 switch (Ti.kind) { |
3737 switch (Ti.kind) { |
3719 case UNBOUND: |
3738 case UNBOUND: |
3720 Si.bound = subst(Ui, A, S); |
3739 Si.bound = subst(Ui, A, S); |
3747 // where |
3766 // where |
3748 public List<Type> freshTypeVariables(List<Type> types) { |
3767 public List<Type> freshTypeVariables(List<Type> types) { |
3749 ListBuffer<Type> result = lb(); |
3768 ListBuffer<Type> result = lb(); |
3750 for (Type t : types) { |
3769 for (Type t : types) { |
3751 if (t.tag == WILDCARD) { |
3770 if (t.tag == WILDCARD) { |
|
3771 t = t.unannotatedType(); |
3752 Type bound = ((WildcardType)t).getExtendsBound(); |
3772 Type bound = ((WildcardType)t).getExtendsBound(); |
3753 if (bound == null) |
3773 if (bound == null) |
3754 bound = syms.objectType; |
3774 bound = syms.objectType; |
3755 result.append(new CapturedType(capturedName, |
3775 result.append(new CapturedType(capturedName, |
3756 syms.noSymbol, |
3776 syms.noSymbol, |
3840 return true; |
3860 return true; |
3841 } |
3861 } |
3842 |
3862 |
3843 private boolean giveWarning(Type from, Type to) { |
3863 private boolean giveWarning(Type from, Type to) { |
3844 List<Type> bounds = to.isCompound() ? |
3864 List<Type> bounds = to.isCompound() ? |
3845 ((IntersectionClassType)to).getComponents() : List.of(to); |
3865 ((IntersectionClassType)to.unannotatedType()).getComponents() : List.of(to); |
3846 for (Type b : bounds) { |
3866 for (Type b : bounds) { |
3847 Type subFrom = asSub(from, b.tsym); |
3867 Type subFrom = asSub(from, b.tsym); |
3848 if (b.isParameterized() && |
3868 if (b.isParameterized() && |
3849 (!(isUnbounded(b) || |
3869 (!(isUnbounded(b) || |
3850 isSubtype(from, b) || |
3870 isSubtype(from, b) || |
4180 return types.hashCode(type); |
4200 return types.hashCode(type); |
4181 } |
4201 } |
4182 |
4202 |
4183 public boolean equals(Object obj) { |
4203 public boolean equals(Object obj) { |
4184 return (obj instanceof UniqueType) && |
4204 return (obj instanceof UniqueType) && |
4185 types.isSameType(type, ((UniqueType)obj).type); |
4205 types.isSameAnnotatedType(type, ((UniqueType)obj).type); |
4186 } |
4206 } |
4187 |
4207 |
4188 public String toString() { |
4208 public String toString() { |
4189 return type.toString(); |
4209 return type.toString(); |
4190 } |
4210 } |