974 /** |
974 /** |
975 * Are corresponding elements of the lists the same type? If |
975 * Are corresponding elements of the lists the same type? If |
976 * lists are of different length, return false. |
976 * lists are of different length, return false. |
977 */ |
977 */ |
978 public boolean isSameTypes(List<Type> ts, List<Type> ss) { |
978 public boolean isSameTypes(List<Type> ts, List<Type> ss) { |
|
979 return isSameTypes(ts, ss, false); |
|
980 } |
|
981 public boolean isSameTypes(List<Type> ts, List<Type> ss, boolean strict) { |
979 while (ts.tail != null && ss.tail != null |
982 while (ts.tail != null && ss.tail != null |
980 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ && |
983 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ && |
981 isSameType(ts.head, ss.head)) { |
984 isSameType(ts.head, ss.head, strict)) { |
982 ts = ts.tail; |
985 ts = ts.tail; |
983 ss = ss.tail; |
986 ss = ss.tail; |
984 } |
987 } |
985 return ts.tail == null && ss.tail == null; |
988 return ts.tail == null && ss.tail == null; |
986 /*inlined: ts.isEmpty() && ss.isEmpty();*/ |
989 /*inlined: ts.isEmpty() && ss.isEmpty();*/ |
988 |
991 |
989 /** |
992 /** |
990 * Is t the same type as s? |
993 * Is t the same type as s? |
991 */ |
994 */ |
992 public boolean isSameType(Type t, Type s) { |
995 public boolean isSameType(Type t, Type s) { |
993 return isSameType.visit(t, s); |
996 return isSameType(t, s, false); |
|
997 } |
|
998 public boolean isSameType(Type t, Type s, boolean strict) { |
|
999 return strict ? |
|
1000 isSameTypeStrict.visit(t, s) : |
|
1001 isSameTypeLoose.visit(t, s); |
994 } |
1002 } |
995 // where |
1003 // where |
996 private TypeRelation isSameType = new TypeRelation() { |
1004 abstract class SameTypeVisitor extends TypeRelation { |
997 |
1005 |
998 public Boolean visitType(Type t, Type s) { |
1006 public Boolean visitType(Type t, Type s) { |
999 if (t == s) |
1007 if (t == s) |
1000 return true; |
1008 return true; |
1001 |
1009 |
1008 return t.tag == s.tag; |
1016 return t.tag == s.tag; |
1009 case TYPEVAR: { |
1017 case TYPEVAR: { |
1010 if (s.tag == TYPEVAR) { |
1018 if (s.tag == TYPEVAR) { |
1011 //type-substitution does not preserve type-var types |
1019 //type-substitution does not preserve type-var types |
1012 //check that type var symbols and bounds are indeed the same |
1020 //check that type var symbols and bounds are indeed the same |
1013 return t.tsym == s.tsym && |
1021 return sameTypeVars((TypeVar)t, (TypeVar)s); |
1014 visit(t.getUpperBound(), s.getUpperBound()); |
|
1015 } |
1022 } |
1016 else { |
1023 else { |
1017 //special case for s == ? super X, where upper(s) = u |
1024 //special case for s == ? super X, where upper(s) = u |
1018 //check that u == t, where u has been set by Type.withTypeVar |
1025 //check that u == t, where u has been set by Type.withTypeVar |
1019 return s.isSuperBound() && |
1026 return s.isSuperBound() && |
1058 } |
1067 } |
1059 return (set.isEmpty()); |
1068 return (set.isEmpty()); |
1060 } |
1069 } |
1061 return t.tsym == s.tsym |
1070 return t.tsym == s.tsym |
1062 && visit(t.getEnclosingType(), s.getEnclosingType()) |
1071 && visit(t.getEnclosingType(), s.getEnclosingType()) |
1063 && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments()); |
1072 && containsTypes(t.getTypeArguments(), s.getTypeArguments()); |
1064 } |
1073 } |
|
1074 |
|
1075 abstract protected boolean containsTypes(List<Type> ts1, List<Type> ts2); |
1065 |
1076 |
1066 @Override |
1077 @Override |
1067 public Boolean visitArrayType(ArrayType t, Type s) { |
1078 public Boolean visitArrayType(ArrayType t, Type s) { |
1068 if (t == s) |
1079 if (t == s) |
1069 return true; |
1080 return true; |
1112 } |
1123 } |
1113 |
1124 |
1114 @Override |
1125 @Override |
1115 public Boolean visitErrorType(ErrorType t, Type s) { |
1126 public Boolean visitErrorType(ErrorType t, Type s) { |
1116 return true; |
1127 return true; |
|
1128 } |
|
1129 } |
|
1130 |
|
1131 /** |
|
1132 * Standard type-equality relation - type variables are considered |
|
1133 * equals if they share the same type symbol. |
|
1134 */ |
|
1135 TypeRelation isSameTypeLoose = new SameTypeVisitor() { |
|
1136 @Override |
|
1137 boolean sameTypeVars(TypeVar tv1, TypeVar tv2) { |
|
1138 return tv1.tsym == tv2.tsym && visit(tv1.getUpperBound(), tv2.getUpperBound()); |
|
1139 } |
|
1140 @Override |
|
1141 protected boolean containsTypes(List<Type> ts1, List<Type> ts2) { |
|
1142 return containsTypeEquivalent(ts1, ts2); |
|
1143 } |
|
1144 }; |
|
1145 |
|
1146 /** |
|
1147 * Strict type-equality relation - type variables are considered |
|
1148 * equals if they share the same object identity. |
|
1149 */ |
|
1150 TypeRelation isSameTypeStrict = new SameTypeVisitor() { |
|
1151 @Override |
|
1152 boolean sameTypeVars(TypeVar tv1, TypeVar tv2) { |
|
1153 return tv1 == tv2; |
|
1154 } |
|
1155 @Override |
|
1156 protected boolean containsTypes(List<Type> ts1, List<Type> ts2) { |
|
1157 return isSameTypes(ts1, ts2, true); |
1117 } |
1158 } |
1118 }; |
1159 }; |
1119 // </editor-fold> |
1160 // </editor-fold> |
1120 |
1161 |
1121 // <editor-fold defaultstate="collapsed" desc="Contains Type"> |
1162 // <editor-fold defaultstate="collapsed" desc="Contains Type"> |
2025 return t; |
2066 return t; |
2026 } |
2067 } |
2027 |
2068 |
2028 @Override |
2069 @Override |
2029 public Type visitAnnotatedType(AnnotatedType t, Boolean recurse) { |
2070 public Type visitAnnotatedType(AnnotatedType t, Boolean recurse) { |
2030 return new AnnotatedType(t.typeAnnotations, erasure(t.underlyingType, recurse)); |
2071 Type erased = erasure(t.underlyingType, recurse); |
|
2072 if (erased.getKind() == TypeKind.ANNOTATED) { |
|
2073 // This can only happen when the underlying type is a |
|
2074 // type variable and the upper bound of it is annotated. |
|
2075 // The annotation on the type variable overrides the one |
|
2076 // on the bound. |
|
2077 erased = ((AnnotatedType)erased).underlyingType; |
|
2078 } |
|
2079 return new AnnotatedType(t.typeAnnotations, erased); |
2031 } |
2080 } |
2032 }; |
2081 }; |
2033 |
2082 |
2034 private Mapping erasureFun = new Mapping ("erasure") { |
2083 private Mapping erasureFun = new Mapping ("erasure") { |
2035 public Type apply(Type t) { return erasure(t); } |
2084 public Type apply(Type t) { return erasure(t); } |