src/share/classes/com/sun/tools/javac/code/Types.java

changeset 2416
63ef1e0410d1
parent 2407
8a5512cb5e9d
child 2420
1aeb322cf646
equal deleted inserted replaced
2415:7ceaee0e497b 2416:63ef1e0410d1
1219 * equals if they share the same type symbol. 1219 * equals if they share the same type symbol.
1220 */ 1220 */
1221 TypeRelation isSameTypeLoose = new LooseSameTypeVisitor(); 1221 TypeRelation isSameTypeLoose = new LooseSameTypeVisitor();
1222 1222
1223 private class LooseSameTypeVisitor extends SameTypeVisitor { 1223 private class LooseSameTypeVisitor extends SameTypeVisitor {
1224
1225 /** cache of the type-variable pairs being (recursively) tested. */
1226 private Set<TypePair> cache = new HashSet<>();
1227
1224 @Override 1228 @Override
1225 boolean sameTypeVars(TypeVar tv1, TypeVar tv2) { 1229 boolean sameTypeVars(TypeVar tv1, TypeVar tv2) {
1226 return tv1.tsym == tv2.tsym && visit(tv1.getUpperBound(), tv2.getUpperBound()); 1230 return tv1.tsym == tv2.tsym && checkSameBounds(tv1, tv2);
1227 } 1231 }
1228 @Override 1232 @Override
1229 protected boolean containsTypes(List<Type> ts1, List<Type> ts2) { 1233 protected boolean containsTypes(List<Type> ts1, List<Type> ts2) {
1230 return containsTypeEquivalent(ts1, ts2); 1234 return containsTypeEquivalent(ts1, ts2);
1235 }
1236
1237 /**
1238 * Since type-variable bounds can be recursive, we need to protect against
1239 * infinite loops - where the same bounds are checked over and over recursively.
1240 */
1241 private boolean checkSameBounds(TypeVar tv1, TypeVar tv2) {
1242 TypePair p = new TypePair(tv1, tv2, true);
1243 if (cache.add(p)) {
1244 try {
1245 return visit(tv1.getUpperBound(), tv2.getUpperBound());
1246 } finally {
1247 cache.remove(p);
1248 }
1249 } else {
1250 return false;
1251 }
1231 } 1252 }
1232 }; 1253 };
1233 1254
1234 /** 1255 /**
1235 * Strict type-equality relation - type variables are considered 1256 * Strict type-equality relation - type variables are considered
3374 } 3395 }
3375 // where 3396 // where
3376 class TypePair { 3397 class TypePair {
3377 final Type t1; 3398 final Type t1;
3378 final Type t2; 3399 final Type t2;
3400 boolean strict;
3401
3379 TypePair(Type t1, Type t2) { 3402 TypePair(Type t1, Type t2) {
3403 this(t1, t2, false);
3404 }
3405
3406 TypePair(Type t1, Type t2, boolean strict) {
3380 this.t1 = t1; 3407 this.t1 = t1;
3381 this.t2 = t2; 3408 this.t2 = t2;
3409 this.strict = strict;
3382 } 3410 }
3383 @Override 3411 @Override
3384 public int hashCode() { 3412 public int hashCode() {
3385 return 127 * Types.this.hashCode(t1) + Types.this.hashCode(t2); 3413 return 127 * Types.this.hashCode(t1) + Types.this.hashCode(t2);
3386 } 3414 }
3387 @Override 3415 @Override
3388 public boolean equals(Object obj) { 3416 public boolean equals(Object obj) {
3389 if (!(obj instanceof TypePair)) 3417 if (!(obj instanceof TypePair))
3390 return false; 3418 return false;
3391 TypePair typePair = (TypePair)obj; 3419 TypePair typePair = (TypePair)obj;
3392 return isSameType(t1, typePair.t1) 3420 return isSameType(t1, typePair.t1, strict)
3393 && isSameType(t2, typePair.t2); 3421 && isSameType(t2, typePair.t2, strict);
3394 } 3422 }
3395 } 3423 }
3396 Set<TypePair> mergeCache = new HashSet<TypePair>(); 3424 Set<TypePair> mergeCache = new HashSet<TypePair>();
3397 private Type merge(Type c1, Type c2) { 3425 private Type merge(Type c1, Type c2) {
3398 ClassType class1 = (ClassType) c1; 3426 ClassType class1 = (ClassType) c1;

mercurial