1.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java Mon Feb 04 18:08:53 2013 -0500 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Sun Feb 17 16:44:55 2013 -0500 1.3 @@ -976,9 +976,12 @@ 1.4 * lists are of different length, return false. 1.5 */ 1.6 public boolean isSameTypes(List<Type> ts, List<Type> ss) { 1.7 + return isSameTypes(ts, ss, false); 1.8 + } 1.9 + public boolean isSameTypes(List<Type> ts, List<Type> ss, boolean strict) { 1.10 while (ts.tail != null && ss.tail != null 1.11 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ && 1.12 - isSameType(ts.head, ss.head)) { 1.13 + isSameType(ts.head, ss.head, strict)) { 1.14 ts = ts.tail; 1.15 ss = ss.tail; 1.16 } 1.17 @@ -990,10 +993,15 @@ 1.18 * Is t the same type as s? 1.19 */ 1.20 public boolean isSameType(Type t, Type s) { 1.21 - return isSameType.visit(t, s); 1.22 + return isSameType(t, s, false); 1.23 + } 1.24 + public boolean isSameType(Type t, Type s, boolean strict) { 1.25 + return strict ? 1.26 + isSameTypeStrict.visit(t, s) : 1.27 + isSameTypeLoose.visit(t, s); 1.28 } 1.29 // where 1.30 - private TypeRelation isSameType = new TypeRelation() { 1.31 + abstract class SameTypeVisitor extends TypeRelation { 1.32 1.33 public Boolean visitType(Type t, Type s) { 1.34 if (t == s) 1.35 @@ -1010,8 +1018,7 @@ 1.36 if (s.tag == TYPEVAR) { 1.37 //type-substitution does not preserve type-var types 1.38 //check that type var symbols and bounds are indeed the same 1.39 - return t.tsym == s.tsym && 1.40 - visit(t.getUpperBound(), s.getUpperBound()); 1.41 + return sameTypeVars((TypeVar)t, (TypeVar)s); 1.42 } 1.43 else { 1.44 //special case for s == ? super X, where upper(s) = u 1.45 @@ -1026,6 +1033,8 @@ 1.46 } 1.47 } 1.48 1.49 + abstract boolean sameTypeVars(TypeVar tv1, TypeVar tv2); 1.50 + 1.51 @Override 1.52 public Boolean visitWildcardType(WildcardType t, Type s) { 1.53 if (s.isPartial()) 1.54 @@ -1060,9 +1069,11 @@ 1.55 } 1.56 return t.tsym == s.tsym 1.57 && visit(t.getEnclosingType(), s.getEnclosingType()) 1.58 - && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments()); 1.59 + && containsTypes(t.getTypeArguments(), s.getTypeArguments()); 1.60 } 1.61 1.62 + abstract protected boolean containsTypes(List<Type> ts1, List<Type> ts2); 1.63 + 1.64 @Override 1.65 public Boolean visitArrayType(ArrayType t, Type s) { 1.66 if (t == s) 1.67 @@ -1115,6 +1126,36 @@ 1.68 public Boolean visitErrorType(ErrorType t, Type s) { 1.69 return true; 1.70 } 1.71 + } 1.72 + 1.73 + /** 1.74 + * Standard type-equality relation - type variables are considered 1.75 + * equals if they share the same type symbol. 1.76 + */ 1.77 + TypeRelation isSameTypeLoose = new SameTypeVisitor() { 1.78 + @Override 1.79 + boolean sameTypeVars(TypeVar tv1, TypeVar tv2) { 1.80 + return tv1.tsym == tv2.tsym && visit(tv1.getUpperBound(), tv2.getUpperBound()); 1.81 + } 1.82 + @Override 1.83 + protected boolean containsTypes(List<Type> ts1, List<Type> ts2) { 1.84 + return containsTypeEquivalent(ts1, ts2); 1.85 + } 1.86 + }; 1.87 + 1.88 + /** 1.89 + * Strict type-equality relation - type variables are considered 1.90 + * equals if they share the same object identity. 1.91 + */ 1.92 + TypeRelation isSameTypeStrict = new SameTypeVisitor() { 1.93 + @Override 1.94 + boolean sameTypeVars(TypeVar tv1, TypeVar tv2) { 1.95 + return tv1 == tv2; 1.96 + } 1.97 + @Override 1.98 + protected boolean containsTypes(List<Type> ts1, List<Type> ts2) { 1.99 + return isSameTypes(ts1, ts2, true); 1.100 + } 1.101 }; 1.102 // </editor-fold> 1.103 1.104 @@ -2027,7 +2068,15 @@ 1.105 1.106 @Override 1.107 public Type visitAnnotatedType(AnnotatedType t, Boolean recurse) { 1.108 - return new AnnotatedType(t.typeAnnotations, erasure(t.underlyingType, recurse)); 1.109 + Type erased = erasure(t.underlyingType, recurse); 1.110 + if (erased.getKind() == TypeKind.ANNOTATED) { 1.111 + // This can only happen when the underlying type is a 1.112 + // type variable and the upper bound of it is annotated. 1.113 + // The annotation on the type variable overrides the one 1.114 + // on the bound. 1.115 + erased = ((AnnotatedType)erased).underlyingType; 1.116 + } 1.117 + return new AnnotatedType(t.typeAnnotations, erased); 1.118 } 1.119 }; 1.120