21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.tools.javac.code;
27
28 import java.lang.ref.SoftReference;
29 import java.util.HashSet;
30 import java.util.HashMap;
31 import java.util.Locale;
32 import java.util.Map;
33 import java.util.Set;
34 import java.util.WeakHashMap;
35
36 import javax.tools.JavaFileObject;
37
38 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
39 import com.sun.tools.javac.code.Lint.LintCategory;
40 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
41 import com.sun.tools.javac.comp.AttrContext;
42 import com.sun.tools.javac.comp.Check;
43 import com.sun.tools.javac.comp.Enter;
44 import com.sun.tools.javac.comp.Env;
45 import com.sun.tools.javac.util.*;
46
47 import static com.sun.tools.javac.code.BoundKind.*;
48 import static com.sun.tools.javac.code.Flags.*;
49 import static com.sun.tools.javac.code.Kinds.Kind.*;
50 import static com.sun.tools.javac.code.Scope.*;
51 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
52 import static com.sun.tools.javac.code.Symbol.*;
53 import static com.sun.tools.javac.code.Type.*;
54 import static com.sun.tools.javac.code.TypeTag.*;
55 import static com.sun.tools.javac.jvm.ClassFile.externalize;
56
57 /**
58 * Utility class containing various operations on types.
59 *
60 * <p>Unless other names are more illustrative, the following naming
778 case CLASS:
779 shouldWarn = from.isVarargs();
780 break;
781 }
782 if (shouldWarn) {
783 warn.warn(LintCategory.VARARGS);
784 }
785 }
786
787 /**
788 * Is t a subtype of s?<br>
789 * (not defined for Method and ForAll types)
790 */
791 final public boolean isSubtype(Type t, Type s) {
792 return isSubtype(t, s, true);
793 }
794 final public boolean isSubtypeNoCapture(Type t, Type s) {
795 return isSubtype(t, s, false);
796 }
797 public boolean isSubtype(Type t, Type s, boolean capture) {
798 if (t == s)
799 return true;
800 if (s.isPartial())
801 return isSuperType(s, t);
802
803 if (s.isCompound()) {
804 for (Type s2 : interfaces(s).prepend(supertype(s))) {
805 if (!isSubtype(t, s2, capture))
806 return false;
807 }
808 return true;
809 }
810
811 // Generally, if 's' is a lower-bounded type variable, recur on lower bound; but
812 // for inference variables and intersections, we need to keep 's'
813 // (see JLS 4.10.2 for intersections and 18.2.3 for inference vars)
814 if (!t.hasTag(UNDETVAR) && !t.isCompound()) {
815 // TODO: JDK-8039198, bounds checking sometimes passes in a wildcard as s
816 Type lower = cvarLowerBound(wildLowerBound(s));
817 if (s != lower && !lower.hasTag(BOT))
818 return isSubtype(capture ? capture(t) : t, lower, false);
1050 List<Type> argtypes = msym.type.getParameterTypes();
1051 return (msym.flags_field & NATIVE) != 0 &&
1052 msym.owner == syms.methodHandleType.tsym &&
1053 argtypes.tail.tail == null &&
1054 argtypes.head.hasTag(TypeTag.ARRAY) &&
1055 msym.type.getReturnType().tsym == syms.objectType.tsym &&
1056 ((ArrayType)argtypes.head).elemtype.tsym == syms.objectType.tsym;
1057 }
1058
1059 /**
1060 * Is t the same type as s?
1061 */
1062 public boolean isSameType(Type t, Type s) {
1063 return isSameType(t, s, false);
1064 }
1065 public boolean isSameType(Type t, Type s, boolean strict) {
1066 return strict ?
1067 isSameTypeStrict.visit(t, s) :
1068 isSameTypeLoose.visit(t, s);
1069 }
1070 public boolean isSameAnnotatedType(Type t, Type s) {
1071 return isSameAnnotatedType.visit(t, s);
1072 }
1073 // where
1074 abstract class SameTypeVisitor extends TypeRelation {
1075
1076 public Boolean visitType(Type t, Type s) {
1077 if (t == s)
1078 return true;
1079
1080 if (s.isPartial())
1081 return visit(s, t);
1082
1083 switch (t.getTag()) {
1084 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
1085 case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE:
1086 return t.hasTag(s.getTag());
1087 case TYPEVAR: {
1088 if (s.hasTag(TYPEVAR)) {
1089 //type-substitution does not preserve type-var types
1090 //check that type var symbols and bounds are indeed the same
1091 return sameTypeVars((TypeVar)t, (TypeVar)s);
1092 }
1093 else {
1094 //special case for s == ? super X, where upper(s) = u
1095 //check that u == t, where u has been set by Type.withTypeVar
1096 return s.isSuperBound() &&
1097 !s.isExtendsBound() &&
1250 }
1251 @Override
1252 protected boolean containsTypes(List<Type> ts1, List<Type> ts2) {
1253 return isSameTypes(ts1, ts2, true);
1254 }
1255
1256 @Override
1257 public Boolean visitWildcardType(WildcardType t, Type s) {
1258 if (!s.hasTag(WILDCARD)) {
1259 return false;
1260 } else {
1261 WildcardType t2 = (WildcardType)s;
1262 return t.kind == t2.kind &&
1263 isSameType(t.type, t2.type, true);
1264 }
1265 }
1266 };
1267
1268 // </editor-fold>
1269
1270 TypeRelation isSameAnnotatedType = new LooseSameTypeVisitor() {
1271 private Boolean compareAnnotations(Type t1, Type t2) {
1272 List<Attribute.TypeCompound> annos1 = t1.getAnnotationMirrors();
1273 List<Attribute.TypeCompound> annos2 = t2.getAnnotationMirrors();
1274 return annos1.containsAll(annos2) && annos2.containsAll(annos1);
1275 }
1276
1277 @Override
1278 public Boolean visitType(Type t, Type s) {
1279 return compareAnnotations(t, s) && super.visitType(t, s);
1280 }
1281
1282 @Override
1283 public Boolean visitWildcardType(WildcardType t, Type s) {
1284 return compareAnnotations(t, s) && super.visitWildcardType(t, s);
1285 }
1286
1287 @Override
1288 public Boolean visitClassType(ClassType t, Type s) {
1289 return compareAnnotations(t, s) && super.visitClassType(t, s);
1290 }
1291
1292 @Override
1293 public Boolean visitArrayType(ArrayType t, Type s) {
1294 return compareAnnotations(t, s) && super.visitArrayType(t, s);
1295 }
1296
1297 @Override
1298 public Boolean visitForAll(ForAll t, Type s) {
1299 return compareAnnotations(t, s) && super.visitForAll(t, s);
1300 }
1301 };
1302
1303 // <editor-fold defaultstate="collapsed" desc="Contains Type">
1304 public boolean containedBy(Type t, Type s) {
1305 switch (t.getTag()) {
1306 case UNDETVAR:
1307 if (s.hasTag(WILDCARD)) {
1308 UndetVar undetvar = (UndetVar)t;
1309 WildcardType wt = (WildcardType)s;
1310 switch(wt.kind) {
1311 case UNBOUND:
1312 break;
1313 case EXTENDS: {
1314 Type bound = wildUpperBound(s);
1315 undetvar.addBound(InferenceBound.UPPER, bound, this);
1316 break;
1317 }
1318 case SUPER: {
1319 Type bound = wildLowerBound(s);
1320 undetvar.addBound(InferenceBound.LOWER, bound, this);
1321 break;
1322 }
2135 case CLASS:
2136 switch (unboxedType(s).getTag()) {
2137 case BYTE:
2138 case CHAR:
2139 case SHORT:
2140 return isAssignable(t, unboxedType(s), warn);
2141 }
2142 break;
2143 }
2144 }
2145 return isConvertible(t, s, warn);
2146 }
2147 // </editor-fold>
2148
2149 // <editor-fold defaultstate="collapsed" desc="erasure">
2150 /**
2151 * The erasure of t {@code |t|} -- the type that results when all
2152 * type parameters in t are deleted.
2153 */
2154 public Type erasure(Type t) {
2155 return eraseNotNeeded(t)? t : erasure(t, false);
2156 }
2157 //where
2158 private boolean eraseNotNeeded(Type t) {
2159 // We don't want to erase primitive types and String type as that
2160 // operation is idempotent. Also, erasing these could result in loss
2161 // of information such as constant values attached to such types.
2162 return (t.isPrimitive()) || (syms.stringType.tsym == t.tsym);
2163 }
2164
2165 private Type erasure(Type t, boolean recurse) {
2166 if (t.isPrimitive()) {
2167 return t; /* fast special case */
2168 } else {
2169 Type out = erasure.visit(t, recurse);
2170 return out;
2171 }
2172 }
2173 // where
2174 private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() {
2175 private Type combineMetadata(final Type ty,
2176 final TypeMetadata md) {
2177 if (!md.isEmpty()) {
2178 switch (ty.getKind()) {
2179 default: return ty.clone(ty.metadata.combine(md));
2180 case OTHER:
2181 case UNION:
2182 case INTERSECTION:
2183 case PACKAGE:
2184 case EXECUTABLE:
2185 case NONE:
2186 case VOID:
2187 case ERROR:
2188 return ty;
2189 }
2190 } else {
2191 return ty;
2192 }
2193 }
2194
2195 public Type visitType(Type t, Boolean recurse) {
2196 if (t.isPrimitive())
2197 return t; /*fast special case*/
2198 else {
2199 Type erased = t.map(recurse ? erasureRecFun : erasureFun);
2200 return combineMetadata(erased, t.getMetadata());
2201 }
2202 }
2203
2204 @Override
2205 public Type visitClassType(ClassType t, Boolean recurse) {
2206 Type erased = t.tsym.erasure(Types.this);
2207 if (recurse) {
2208 erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym, t.getMetadata());
2209 return erased;
2210 } else {
2211 return combineMetadata(erased, t.getMetadata());
2212 }
2213 }
2214
2215 @Override
2216 public Type visitTypeVar(TypeVar t, Boolean recurse) {
2217 Type erased = erasure(t.bound, recurse);
2218 return combineMetadata(erased, t.getMetadata());
2219 }
2220
2221 @Override
2222 public Type visitErrorType(ErrorType t, Boolean recurse) {
2223 return t;
2224 }
2225 };
2226
2227 private Mapping erasureFun = new Mapping ("erasure") {
2228 public Type apply(Type t) { return erasure(t); }
2229 };
2230
2231 private Mapping erasureRecFun = new Mapping ("erasureRecursive") {
2232 public Type apply(Type t) { return erasureRecursive(t); }
2233 };
2234
2235 public List<Type> erasure(List<Type> ts) {
2236 return Type.map(ts, erasureFun);
2237 }
2238
2942 public Type subst(Type t, List<Type> from, List<Type> to) {
2943 return new Subst(from, to).subst(t);
2944 }
2945
2946 private class Subst extends UnaryVisitor<Type> {
2947 List<Type> from;
2948 List<Type> to;
2949
2950 public Subst(List<Type> from, List<Type> to) {
2951 int fromLength = from.length();
2952 int toLength = to.length();
2953 while (fromLength > toLength) {
2954 fromLength--;
2955 from = from.tail;
2956 }
2957 while (fromLength < toLength) {
2958 toLength--;
2959 to = to.tail;
2960 }
2961 this.from = from;
2962 this.to = to;
2963 }
2964
2965 Type subst(Type t) {
2966 if (from.tail == null)
2967 return t;
2968 else
2969 return visit(t);
2970 }
2971
2972 List<Type> subst(List<Type> ts) {
2973 if (from.tail == null)
2974 return ts;
2975 boolean wild = false;
2976 if (ts.nonEmpty() && from.nonEmpty()) {
2977 Type head1 = subst(ts.head);
2978 List<Type> tail1 = subst(ts.tail);
2979 if (head1 != ts.head || tail1 != ts.tail)
2980 return tail1.prepend(head1);
2981 }
2982 return ts;
2983 }
2984
2985 public Type visitType(Type t, Void ignored) {
2986 return t;
2987 }
2988
2989 @Override
2990 public Type visitMethodType(MethodType t, Void ignored) {
2991 List<Type> argtypes = subst(t.argtypes);
2992 Type restype = subst(t.restype);
2993 List<Type> thrown = subst(t.thrown);
2994 if (argtypes == t.argtypes &&
2995 restype == t.restype &&
2996 thrown == t.thrown)
2997 return t;
2998 else
2999 return new MethodType(argtypes, restype, thrown, t.tsym);
3000 }
3001
3002 @Override
3003 public Type visitTypeVar(TypeVar t, Void ignored) {
3004 for (List<Type> from = this.from, to = this.to;
3005 from.nonEmpty();
3006 from = from.tail, to = to.tail) {
3007 if (t == from.head) {
3008 return to.head.withTypeVar(t);
3009 }
3010 }
3011 return t;
3012 }
3013
3014 @Override
3015 public Type visitUndetVar(UndetVar t, Void ignored) {
3016 //do nothing - we should not replace inside undet variables
3017 return t;
3018 }
3019
3020 @Override
3021 public Type visitClassType(ClassType t, Void ignored) {
3022 if (!t.isCompound()) {
3023 List<Type> typarams = t.getTypeArguments();
3024 List<Type> typarams1 = subst(typarams);
3025 Type outer = t.getEnclosingType();
3026 Type outer1 = subst(outer);
3027 if (typarams1 == typarams && outer1 == outer)
3137 return t;
3138 else {
3139 // create new type variable without bounds
3140 TypeVar tv = new TypeVar(t.tsym, null, syms.botType,
3141 t.getMetadata());
3142 // the new bound should use the new type variable in place
3143 // of the old
3144 tv.bound = subst(bound1, List.<Type>of(t), List.<Type>of(tv));
3145 return tv;
3146 }
3147 }
3148 // </editor-fold>
3149
3150 // <editor-fold defaultstate="collapsed" desc="hasSameBounds">
3151 /**
3152 * Does t have the same bounds for quantified variables as s?
3153 */
3154 public boolean hasSameBounds(ForAll t, ForAll s) {
3155 List<Type> l1 = t.tvars;
3156 List<Type> l2 = s.tvars;
3157 while (l1.nonEmpty() && l2.nonEmpty() &&
3158 isSameType(l1.head.getUpperBound(),
3159 subst(l2.head.getUpperBound(),
3160 s.tvars,
3161 t.tvars))) {
3162 l1 = l1.tail;
3163 l2 = l2.tail;
3164 }
3165 return l1.isEmpty() && l2.isEmpty();
3166 }
3167 // </editor-fold>
3168
3169 // <editor-fold defaultstate="collapsed" desc="newInstances">
3170 /** Create new vector of type variables from list of variables
3171 * changing all recursive bounds from old to new list.
3172 */
3173 public List<Type> newInstances(List<Type> tvars) {
3174 List<Type> tvars1 = Type.map(tvars, newInstanceFun);
3175 for (List<Type> l = tvars1; l.nonEmpty(); l = l.tail) {
3176 TypeVar tv = (TypeVar) l.head;
3177 tv.bound = subst(tv.bound, tvars, tvars1);
3178 }
3179 return tvars1;
3180 }
3181 private static final Mapping newInstanceFun = new Mapping("newInstanceFun") {
3182 public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound(), t.getMetadata()); }
3183 };
4165 ((subFrom != null) && containsType(b.allparams(), subFrom.allparams()))))) {
4166 return true;
4167 }
4168 }
4169 return false;
4170 }
4171
4172 private List<Type> superClosure(Type t, Type s) {
4173 List<Type> cl = List.nil();
4174 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
4175 if (isSubtype(s, erasure(l.head))) {
4176 cl = insert(cl, l.head);
4177 } else {
4178 cl = union(cl, superClosure(l.head, s));
4179 }
4180 }
4181 return cl;
4182 }
4183
4184 private boolean containsTypeEquivalent(Type t, Type s) {
4185 return
4186 isSameType(t, s) || // shortcut
4187 containsType(t, s) && containsType(s, t);
4188 }
4189
4190 // <editor-fold defaultstate="collapsed" desc="adapt">
4191 /**
4192 * Adapt a type by computing a substitution which maps a source
4193 * type to a target type.
4194 *
4195 * @param source the source type
4196 * @param target the target type
4197 * @param from the type variables of the computed substitution
4198 * @param to the types of the computed substitution.
4199 */
4200 public void adapt(Type source,
4201 Type target,
4202 ListBuffer<Type> from,
4203 ListBuffer<Type> to) throws AdaptFailure {
4204 new Adapter(from, to).adapt(source, target);
4205 }
4206
4207 class Adapter extends SimpleVisitor<Void, Type> {
4608 * mapping (mapping a type to itself). This can be overridden in
4609 * subclasses.
4610 *
4611 * @param <S> the type of the second argument (the first being the
4612 * type itself) of this mapping; use Void if a second argument is
4613 * not needed.
4614 */
4615 public static class MapVisitor<S> extends DefaultTypeVisitor<Type,S> {
4616 final public Type visit(Type t) { return t.accept(this, null); }
4617 public Type visitType(Type t, S s) { return t; }
4618 }
4619 // </editor-fold>
4620
4621
4622 // <editor-fold defaultstate="collapsed" desc="Annotation support">
4623
4624 public RetentionPolicy getRetention(Attribute.Compound a) {
4625 return getRetention(a.type.tsym);
4626 }
4627
4628 public RetentionPolicy getRetention(Symbol sym) {
4629 RetentionPolicy vis = RetentionPolicy.CLASS; // the default
4630 Attribute.Compound c = sym.attribute(syms.retentionType.tsym);
4631 if (c != null) {
4632 Attribute value = c.member(names.value);
4633 if (value != null && value instanceof Attribute.Enum) {
4634 Name levelName = ((Attribute.Enum)value).value.name;
4635 if (levelName == names.SOURCE) vis = RetentionPolicy.SOURCE;
4636 else if (levelName == names.CLASS) vis = RetentionPolicy.CLASS;
4637 else if (levelName == names.RUNTIME) vis = RetentionPolicy.RUNTIME;
4638 else ;// /* fail soft */ throw new AssertionError(levelName);
4639 }
4640 }
4641 return vis;
4642 }
4643 // </editor-fold>
4644
4645 // <editor-fold defaultstate="collapsed" desc="Signature Generation">
4646
4647 public static abstract class SignatureGenerator {
4648
4649 private final Types types;
4650
4651 protected abstract void append(char ch);
4652 protected abstract void append(byte[] ba);
4653 protected abstract void append(Name name);
4654 protected void classReference(ClassSymbol c) { /* by default: no-op */ }
4655
4656 protected SignatureGenerator(Types types) {
4657 this.types = types;
4658 }
4659
4660 /**
4661 * Assemble signature of given type in string buffer.
4662 */
4797 assembleSig(l.head);
4798 }
4799 }
4800 append('>');
4801 }
4802
4803 private void assembleSig(List<Type> types) {
4804 for (List<Type> ts = types; ts.nonEmpty(); ts = ts.tail) {
4805 assembleSig(ts.head);
4806 }
4807 }
4808 }
4809 // </editor-fold>
4810
4811 public void newRound() {
4812 descCache._map.clear();
4813 isDerivedRawCache.clear();
4814 implCache._map.clear();
4815 membersCache._map.clear();
4816 closureCache.clear();
4817 }
4818 }
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.tools.javac.code;
27
28 import java.lang.ref.SoftReference;
29 import java.util.HashSet;
30 import java.util.HashMap;
31 import java.util.Locale;
32 import java.util.Map;
33 import java.util.Set;
34 import java.util.WeakHashMap;
35
36 import javax.tools.JavaFileObject;
37
38 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
39 import com.sun.tools.javac.code.Lint.LintCategory;
40 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
41 import com.sun.tools.javac.code.TypeMetadata.Entry.Kind;
42 import com.sun.tools.javac.comp.AttrContext;
43 import com.sun.tools.javac.comp.Check;
44 import com.sun.tools.javac.comp.Enter;
45 import com.sun.tools.javac.comp.Env;
46 import com.sun.tools.javac.util.*;
47
48 import static com.sun.tools.javac.code.BoundKind.*;
49 import static com.sun.tools.javac.code.Flags.*;
50 import static com.sun.tools.javac.code.Kinds.Kind.*;
51 import static com.sun.tools.javac.code.Scope.*;
52 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
53 import static com.sun.tools.javac.code.Symbol.*;
54 import static com.sun.tools.javac.code.Type.*;
55 import static com.sun.tools.javac.code.TypeTag.*;
56 import static com.sun.tools.javac.jvm.ClassFile.externalize;
57
58 /**
59 * Utility class containing various operations on types.
60 *
61 * <p>Unless other names are more illustrative, the following naming
779 case CLASS:
780 shouldWarn = from.isVarargs();
781 break;
782 }
783 if (shouldWarn) {
784 warn.warn(LintCategory.VARARGS);
785 }
786 }
787
788 /**
789 * Is t a subtype of s?<br>
790 * (not defined for Method and ForAll types)
791 */
792 final public boolean isSubtype(Type t, Type s) {
793 return isSubtype(t, s, true);
794 }
795 final public boolean isSubtypeNoCapture(Type t, Type s) {
796 return isSubtype(t, s, false);
797 }
798 public boolean isSubtype(Type t, Type s, boolean capture) {
799 if (t.equalsIgnoreMetadata(s))
800 return true;
801 if (s.isPartial())
802 return isSuperType(s, t);
803
804 if (s.isCompound()) {
805 for (Type s2 : interfaces(s).prepend(supertype(s))) {
806 if (!isSubtype(t, s2, capture))
807 return false;
808 }
809 return true;
810 }
811
812 // Generally, if 's' is a lower-bounded type variable, recur on lower bound; but
813 // for inference variables and intersections, we need to keep 's'
814 // (see JLS 4.10.2 for intersections and 18.2.3 for inference vars)
815 if (!t.hasTag(UNDETVAR) && !t.isCompound()) {
816 // TODO: JDK-8039198, bounds checking sometimes passes in a wildcard as s
817 Type lower = cvarLowerBound(wildLowerBound(s));
818 if (s != lower && !lower.hasTag(BOT))
819 return isSubtype(capture ? capture(t) : t, lower, false);
1051 List<Type> argtypes = msym.type.getParameterTypes();
1052 return (msym.flags_field & NATIVE) != 0 &&
1053 msym.owner == syms.methodHandleType.tsym &&
1054 argtypes.tail.tail == null &&
1055 argtypes.head.hasTag(TypeTag.ARRAY) &&
1056 msym.type.getReturnType().tsym == syms.objectType.tsym &&
1057 ((ArrayType)argtypes.head).elemtype.tsym == syms.objectType.tsym;
1058 }
1059
1060 /**
1061 * Is t the same type as s?
1062 */
1063 public boolean isSameType(Type t, Type s) {
1064 return isSameType(t, s, false);
1065 }
1066 public boolean isSameType(Type t, Type s, boolean strict) {
1067 return strict ?
1068 isSameTypeStrict.visit(t, s) :
1069 isSameTypeLoose.visit(t, s);
1070 }
1071 // where
1072 abstract class SameTypeVisitor extends TypeRelation {
1073
1074 public Boolean visitType(Type t, Type s) {
1075 if (t.equalsIgnoreMetadata(s))
1076 return true;
1077
1078 if (s.isPartial())
1079 return visit(s, t);
1080
1081 switch (t.getTag()) {
1082 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
1083 case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE:
1084 return t.hasTag(s.getTag());
1085 case TYPEVAR: {
1086 if (s.hasTag(TYPEVAR)) {
1087 //type-substitution does not preserve type-var types
1088 //check that type var symbols and bounds are indeed the same
1089 return sameTypeVars((TypeVar)t, (TypeVar)s);
1090 }
1091 else {
1092 //special case for s == ? super X, where upper(s) = u
1093 //check that u == t, where u has been set by Type.withTypeVar
1094 return s.isSuperBound() &&
1095 !s.isExtendsBound() &&
1248 }
1249 @Override
1250 protected boolean containsTypes(List<Type> ts1, List<Type> ts2) {
1251 return isSameTypes(ts1, ts2, true);
1252 }
1253
1254 @Override
1255 public Boolean visitWildcardType(WildcardType t, Type s) {
1256 if (!s.hasTag(WILDCARD)) {
1257 return false;
1258 } else {
1259 WildcardType t2 = (WildcardType)s;
1260 return t.kind == t2.kind &&
1261 isSameType(t.type, t2.type, true);
1262 }
1263 }
1264 };
1265
1266 // </editor-fold>
1267
1268 // <editor-fold defaultstate="collapsed" desc="Contains Type">
1269 public boolean containedBy(Type t, Type s) {
1270 switch (t.getTag()) {
1271 case UNDETVAR:
1272 if (s.hasTag(WILDCARD)) {
1273 UndetVar undetvar = (UndetVar)t;
1274 WildcardType wt = (WildcardType)s;
1275 switch(wt.kind) {
1276 case UNBOUND:
1277 break;
1278 case EXTENDS: {
1279 Type bound = wildUpperBound(s);
1280 undetvar.addBound(InferenceBound.UPPER, bound, this);
1281 break;
1282 }
1283 case SUPER: {
1284 Type bound = wildLowerBound(s);
1285 undetvar.addBound(InferenceBound.LOWER, bound, this);
1286 break;
1287 }
2100 case CLASS:
2101 switch (unboxedType(s).getTag()) {
2102 case BYTE:
2103 case CHAR:
2104 case SHORT:
2105 return isAssignable(t, unboxedType(s), warn);
2106 }
2107 break;
2108 }
2109 }
2110 return isConvertible(t, s, warn);
2111 }
2112 // </editor-fold>
2113
2114 // <editor-fold defaultstate="collapsed" desc="erasure">
2115 /**
2116 * The erasure of t {@code |t|} -- the type that results when all
2117 * type parameters in t are deleted.
2118 */
2119 public Type erasure(Type t) {
2120 return eraseNotNeeded(t)? stripAnnotations(t) : erasure(t, false);
2121 }
2122 //where
2123 private boolean eraseNotNeeded(Type t) {
2124 // We don't want to erase primitive types and String type as that
2125 // operation is idempotent. Also, erasing these could result in loss
2126 // of information such as constant values attached to such types.
2127 return (t.isPrimitive()) || (syms.stringType.tsym == t.tsym);
2128 }
2129
2130 private Type erasure(Type t, boolean recurse) {
2131 if (t.isPrimitive()) {
2132 return stripAnnotations(t); /* fast special case */
2133 } else {
2134 Type out = erasure.visit(t, recurse);
2135 return out;
2136 }
2137 }
2138 // where
2139 private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() {
2140 private Type combineMetadata(final Type s, final Type t) {
2141 if (!t.getMetadata().isEmpty()) {
2142 switch (s.getKind()) {
2143 case OTHER:
2144 case UNION:
2145 case INTERSECTION:
2146 case PACKAGE:
2147 case EXECUTABLE:
2148 case NONE:
2149 case VOID:
2150 case ERROR:
2151 return s;
2152 default:
2153 return s.cloneWithMetadata(t.getMetadata().without(Kind.ANNOTATIONS));
2154 }
2155 } else {
2156 return s;
2157 }
2158 }
2159
2160 public Type visitType(Type t, Boolean recurse) {
2161 if (t.isPrimitive())
2162 return stripAnnotations(t); /*fast special case*/
2163 else {
2164 Type erased = t.map(recurse ? erasureRecFun : erasureFun);
2165 return combineMetadata(erased, t);
2166 }
2167 }
2168
2169 @Override
2170 public Type visitClassType(ClassType t, Boolean recurse) {
2171 Type erased = t.tsym.erasure(Types.this);
2172 if (recurse) {
2173 erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym,
2174 t.getMetadata().without(Kind.ANNOTATIONS));
2175 return erased;
2176 } else {
2177 return combineMetadata(erased, t);
2178 }
2179 }
2180
2181 @Override
2182 public Type visitTypeVar(TypeVar t, Boolean recurse) {
2183 Type erased = erasure(t.bound, recurse);
2184 return combineMetadata(erased, t);
2185 }
2186
2187 @Override
2188 public Type visitErrorType(ErrorType t, Boolean recurse) {
2189 return t;
2190 }
2191 };
2192
2193 private Mapping erasureFun = new Mapping ("erasure") {
2194 public Type apply(Type t) { return erasure(t); }
2195 };
2196
2197 private Mapping erasureRecFun = new Mapping ("erasureRecursive") {
2198 public Type apply(Type t) { return erasureRecursive(t); }
2199 };
2200
2201 public List<Type> erasure(List<Type> ts) {
2202 return Type.map(ts, erasureFun);
2203 }
2204
2908 public Type subst(Type t, List<Type> from, List<Type> to) {
2909 return new Subst(from, to).subst(t);
2910 }
2911
2912 private class Subst extends UnaryVisitor<Type> {
2913 List<Type> from;
2914 List<Type> to;
2915
2916 public Subst(List<Type> from, List<Type> to) {
2917 int fromLength = from.length();
2918 int toLength = to.length();
2919 while (fromLength > toLength) {
2920 fromLength--;
2921 from = from.tail;
2922 }
2923 while (fromLength < toLength) {
2924 toLength--;
2925 to = to.tail;
2926 }
2927 this.from = from;
2928 this.to = stripAnnotations(to);
2929 }
2930
2931 Type subst(Type t) {
2932 if (from.tail == null)
2933 return t;
2934 else
2935 return visit(t);
2936 }
2937
2938 List<Type> subst(List<Type> ts) {
2939 if (from.tail == null)
2940 return ts;
2941 if (ts.nonEmpty() && from.nonEmpty()) {
2942 Type head1 = subst(ts.head);
2943 List<Type> tail1 = subst(ts.tail);
2944 if (head1 != ts.head || tail1 != ts.tail)
2945 return tail1.prepend(head1);
2946 }
2947 return ts;
2948 }
2949
2950 public Type visitType(Type t, Void ignored) {
2951 return t;
2952 }
2953
2954 @Override
2955 public Type visitMethodType(MethodType t, Void ignored) {
2956 List<Type> argtypes = subst(t.argtypes);
2957 Type restype = subst(t.restype);
2958 List<Type> thrown = subst(t.thrown);
2959 if (argtypes == t.argtypes &&
2960 restype == t.restype &&
2961 thrown == t.thrown)
2962 return t;
2963 else
2964 return new MethodType(argtypes, restype, thrown, t.tsym);
2965 }
2966
2967 @Override
2968 public Type visitTypeVar(TypeVar t, Void ignored) {
2969 for (List<Type> from = this.from, to = this.to;
2970 from.nonEmpty();
2971 from = from.tail, to = to.tail) {
2972 if (t.equalsIgnoreMetadata(from.head)) {
2973 return to.head.withTypeVar(t);
2974 }
2975 }
2976 return t;
2977 }
2978
2979 @Override
2980 public Type visitUndetVar(UndetVar t, Void ignored) {
2981 //do nothing - we should not replace inside undet variables
2982 return t;
2983 }
2984
2985 @Override
2986 public Type visitClassType(ClassType t, Void ignored) {
2987 if (!t.isCompound()) {
2988 List<Type> typarams = t.getTypeArguments();
2989 List<Type> typarams1 = subst(typarams);
2990 Type outer = t.getEnclosingType();
2991 Type outer1 = subst(outer);
2992 if (typarams1 == typarams && outer1 == outer)
3102 return t;
3103 else {
3104 // create new type variable without bounds
3105 TypeVar tv = new TypeVar(t.tsym, null, syms.botType,
3106 t.getMetadata());
3107 // the new bound should use the new type variable in place
3108 // of the old
3109 tv.bound = subst(bound1, List.<Type>of(t), List.<Type>of(tv));
3110 return tv;
3111 }
3112 }
3113 // </editor-fold>
3114
3115 // <editor-fold defaultstate="collapsed" desc="hasSameBounds">
3116 /**
3117 * Does t have the same bounds for quantified variables as s?
3118 */
3119 public boolean hasSameBounds(ForAll t, ForAll s) {
3120 List<Type> l1 = t.tvars;
3121 List<Type> l2 = s.tvars;
3122 while (l1.nonEmpty() && l2.nonEmpty()) {
3123 Type b1 = l1.head.getUpperBound();
3124 Type b2 = subst(l2.head.getUpperBound(), s.tvars, t.tvars);
3125
3126 // Shortcut, most bounds are not annotated
3127 if (isSameType(b1, b2) || isSameType(stripAnnotations(b1), stripAnnotations(b2))) {
3128 l1 = l1.tail;
3129 l2 = l2.tail;
3130 } else {
3131 break;
3132 }
3133 }
3134 return l1.isEmpty() && l2.isEmpty();
3135 }
3136 // </editor-fold>
3137
3138 // <editor-fold defaultstate="collapsed" desc="newInstances">
3139 /** Create new vector of type variables from list of variables
3140 * changing all recursive bounds from old to new list.
3141 */
3142 public List<Type> newInstances(List<Type> tvars) {
3143 List<Type> tvars1 = Type.map(tvars, newInstanceFun);
3144 for (List<Type> l = tvars1; l.nonEmpty(); l = l.tail) {
3145 TypeVar tv = (TypeVar) l.head;
3146 tv.bound = subst(tv.bound, tvars, tvars1);
3147 }
3148 return tvars1;
3149 }
3150 private static final Mapping newInstanceFun = new Mapping("newInstanceFun") {
3151 public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound(), t.getMetadata()); }
3152 };
4134 ((subFrom != null) && containsType(b.allparams(), subFrom.allparams()))))) {
4135 return true;
4136 }
4137 }
4138 return false;
4139 }
4140
4141 private List<Type> superClosure(Type t, Type s) {
4142 List<Type> cl = List.nil();
4143 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
4144 if (isSubtype(s, erasure(l.head))) {
4145 cl = insert(cl, l.head);
4146 } else {
4147 cl = union(cl, superClosure(l.head, s));
4148 }
4149 }
4150 return cl;
4151 }
4152
4153 private boolean containsTypeEquivalent(Type t, Type s) {
4154 boolean res = isSameType(t, s) || // shortcut
4155 containsType(t, s) && containsType(s, t);
4156 if (res)
4157 return res;
4158 Type t1 = stripAnnotations(t);
4159 Type t2 = stripAnnotations(s);
4160 return isSameType(t1, t2) || containsType(t1, t2) && containsType(t2, t1);
4161 }
4162
4163 // <editor-fold defaultstate="collapsed" desc="adapt">
4164 /**
4165 * Adapt a type by computing a substitution which maps a source
4166 * type to a target type.
4167 *
4168 * @param source the source type
4169 * @param target the target type
4170 * @param from the type variables of the computed substitution
4171 * @param to the types of the computed substitution.
4172 */
4173 public void adapt(Type source,
4174 Type target,
4175 ListBuffer<Type> from,
4176 ListBuffer<Type> to) throws AdaptFailure {
4177 new Adapter(from, to).adapt(source, target);
4178 }
4179
4180 class Adapter extends SimpleVisitor<Void, Type> {
4581 * mapping (mapping a type to itself). This can be overridden in
4582 * subclasses.
4583 *
4584 * @param <S> the type of the second argument (the first being the
4585 * type itself) of this mapping; use Void if a second argument is
4586 * not needed.
4587 */
4588 public static class MapVisitor<S> extends DefaultTypeVisitor<Type,S> {
4589 final public Type visit(Type t) { return t.accept(this, null); }
4590 public Type visitType(Type t, S s) { return t; }
4591 }
4592 // </editor-fold>
4593
4594
4595 // <editor-fold defaultstate="collapsed" desc="Annotation support">
4596
4597 public RetentionPolicy getRetention(Attribute.Compound a) {
4598 return getRetention(a.type.tsym);
4599 }
4600
4601 public RetentionPolicy getRetention(TypeSymbol sym) {
4602 RetentionPolicy vis = RetentionPolicy.CLASS; // the default
4603 Attribute.Compound c = sym.attribute(syms.retentionType.tsym);
4604 if (c != null) {
4605 Attribute value = c.member(names.value);
4606 if (value != null && value instanceof Attribute.Enum) {
4607 Name levelName = ((Attribute.Enum)value).value.name;
4608 if (levelName == names.SOURCE) vis = RetentionPolicy.SOURCE;
4609 else if (levelName == names.CLASS) vis = RetentionPolicy.CLASS;
4610 else if (levelName == names.RUNTIME) vis = RetentionPolicy.RUNTIME;
4611 else ;// /* fail soft */ throw new AssertionError(levelName);
4612 }
4613 }
4614 return vis;
4615 }
4616
4617 public List<Type> stripAnnotations(List<Type> types) {
4618 List<Type> res = List.nil();
4619 StripAnnotations strip = new StripAnnotations();
4620 for (Type t : types)
4621 res = res.prepend(strip.visit(t));
4622 return res.reverse();
4623 }
4624
4625 public Type stripAnnotations(Type t) {
4626 return new StripAnnotations().visit(t);
4627 }
4628 // where
4629 private Map<Type, Type> cachedUnannotated = new HashMap<>();
4630 private class StripAnnotations extends UnaryVisitor<Type> {
4631 private Map<Type, Type> lock = new HashMap<>();
4632
4633 public Type visit1(Type t) {
4634 if (t == null)
4635 return null;
4636 return visit(t, null);
4637 }
4638
4639 public List<Type> visit(List<Type> ts) {
4640 if (ts == null)
4641 return null;
4642
4643 List<Type> res = List.nil();
4644 for (Type t : ts)
4645 res = res.prepend(visit(t));
4646 return res.reverse();
4647 }
4648
4649 @Override
4650 public Type visitType(Type t, Void v) {
4651 if (t == null)
4652 return null;
4653
4654 Type cached = cachedUnannotated.get(t);
4655 if (cached != null)
4656 return cached;
4657
4658 Type res = t;
4659 if (t.isAnnotated()) {
4660 // cloneWithMetadata sets underlying type
4661 res = t.cloneWithMetadata(t.getMetadata().without(Kind.ANNOTATIONS));
4662 }
4663 cachedUnannotated.put(t, res);
4664 return t;
4665 }
4666
4667 @Override
4668 public Type visitClassType(ClassType t, Void s) {
4669 Type cached = cachedUnannotated.get(t);
4670 if (cached != null)
4671 return cached;
4672
4673 if (lock.containsKey(t))
4674 return lock.get(t);
4675
4676 // we are first
4677 final Type underlying = t.underlyingTypeOrType();
4678 Type outer = t.getEnclosingType();
4679 Type outer1 = outer == Type.noType ? outer : visit(outer);
4680
4681 List<Type> typarams = t.getTypeArguments();
4682 List<Type> typarams1 = visit(typarams);
4683 ClassType res = new ClassType(outer1, typarams1 ,t.tsym,
4684 t.getMetadata().without(Kind.ANNOTATIONS)) {
4685 @Override
4686 public Type underlyingType() {
4687 return underlying;
4688 }
4689 };
4690
4691 lock.put(t, res);
4692
4693 try {
4694 Type superType = visit1(t.supertype_field);
4695 List<Type> interfaces = visit(t.interfaces_field);
4696
4697 res.supertype_field = superType;
4698 res.interfaces_field = interfaces;
4699 } finally {
4700 lock.remove(t);
4701 }
4702
4703 if (t.getMetadataOfKind(Kind.ANNOTATIONS) == null &&
4704 res.supertype_field == t.supertype_field &&
4705 allEq(res.interfaces_field, t.interfaces_field) &&
4706 outer1 == outer &&
4707 allEq(typarams1, typarams))
4708 res = t;
4709
4710 cachedUnannotated.put(t, res);
4711 return res;
4712 }
4713 // where
4714 boolean allEq(List<?> xs, List<?> ys) {
4715 if (xs == null || ys == null)
4716 return xs == ys;
4717 while (xs.tail != null && ys.tail != null) {
4718 if (xs.head != ys.head) return false;
4719 xs = xs.tail;
4720 ys = ys.tail;
4721 }
4722 return xs.tail == null && ys.tail == null;
4723 }
4724
4725 @Override
4726 public Type visitWildcardType(WildcardType wt, Void s) {
4727 Type cached = cachedUnannotated.get(wt);
4728 if (cached != null)
4729 return cached;
4730
4731 Type t = wt.type;
4732 if (t != null)
4733 t = visit(t);
4734 if (t == wt.type &&! wt.isAnnotated()) {
4735 cachedUnannotated.put(wt,wt);
4736 return wt;
4737 }
4738
4739 final Type underlying = wt.underlyingTypeOrType();
4740 Type res = new WildcardType(t, wt.kind, wt.tsym, wt.bound,
4741 wt.getMetadata().without(Kind.ANNOTATIONS)) {
4742 @Override
4743 public Type underlyingType() {
4744 return underlying;
4745 }
4746 };
4747 cachedUnannotated.put(wt, res);
4748 return res;
4749 }
4750
4751 @Override
4752 public Type visitArrayType(ArrayType t, Void s) {
4753 Type cached = cachedUnannotated.get(t);
4754 if (cached != null)
4755 return cached;
4756
4757 Type elemtype = visit(t.elemtype);
4758 if (elemtype == t.elemtype && !t.isAnnotated()) {
4759 cachedUnannotated.put(t, t);
4760 return t;
4761 }
4762
4763 ArrayType underlying = (ArrayType)t.underlyingTypeOrType();
4764 ArrayType res = new ArrayType(elemtype, underlying.tsym,
4765 t.metadata.without(Kind.ANNOTATIONS)) {
4766 @Override
4767 public ArrayType underlyingType() {
4768 return underlying;
4769 }
4770 };
4771 cachedUnannotated.put(t, res);
4772 return res;
4773 }
4774
4775 @Override
4776 public Type visitMethodType(MethodType t, Void s) { return visitType(t, s); }
4777
4778 @Override
4779 public Type visitPackageType(PackageType t, Void s) { return visitType(t, s); }
4780
4781 @Override
4782 public Type visitTypeVar(TypeVar t, Void s) {
4783 Type cached = cachedUnannotated.get(t);
4784 if (cached != null)
4785 return cached;
4786
4787 if (! hasAnyAnnotations(t)) {
4788 cachedUnannotated.put(t, t);
4789 return t;
4790 }
4791
4792 final TypeVar underlying = (TypeVar)t.underlyingTypeOrType();
4793
4794 if (lock.containsKey(underlying))
4795 return lock.get(underlying); // bounds will be updated by first visit
4796
4797 // We are the first visit and something in t is annotated
4798 TypeVar res = new TypeVar(underlying.tsym, underlying.bound,
4799 underlying.lower, t.getMetadata().without(Kind.ANNOTATIONS))
4800 {
4801 @Override
4802 public TypeVar underlyingType() {
4803 return underlying;
4804 }
4805 };
4806 lock.put(underlying, res);
4807 try {
4808 Type bound = visit(underlying.bound);
4809 Type lower = visit(underlying.lower);
4810
4811 // Bypass setBounds someone else has aready done the right thing there
4812 if (bound != underlying.bound)
4813 res.bound = bound;
4814 if (lower != underlying.lower)
4815 res.lower = lower;
4816 } finally {
4817 lock.remove(underlying);
4818 }
4819
4820 cachedUnannotated.put(t, res);
4821 return res;
4822 }
4823
4824 @Override
4825 public Type visitCapturedType(CapturedType t, Void s) { return visitType(t, s); }
4826
4827 @Override
4828 public Type visitForAll(ForAll t, Void s) { return visitType(t, s); }
4829
4830 @Override
4831 public Type visitUndetVar(UndetVar t, Void s) { return visitType(t, s); }
4832
4833 @Override
4834 public Type visitErrorType(ErrorType t, Void s) { return visitType(t, s); }
4835 }
4836
4837 public boolean hasAnyAnnotations(Type t) {
4838 if (cachedUnannotated.containsKey(t))
4839 return false;
4840 return new HasAnyAnnotations().visit(t);
4841 }
4842
4843 private class HasAnyAnnotations extends SimpleVisitor<Boolean, Void> {
4844 private Set<Type> lock = new HashSet<>();
4845
4846 public boolean visit(List<Type> ts) {
4847 if (ts == null)
4848 return false;
4849
4850 for(Type t : ts)
4851 if (visit(t))
4852 return true;
4853
4854 return false;
4855 }
4856
4857 public boolean visit(Type t) {
4858 if (t == null)
4859 return false;
4860 if (cachedUnannotated.containsKey(t))
4861 return false;
4862 return visit(t, null);
4863 }
4864
4865 @Override
4866 public Boolean visitType(Type t, Void ignore) {
4867 return t.isAnnotated();
4868 }
4869
4870 @Override
4871 public Boolean visitWildcardType(WildcardType t, Void ignore) {
4872 return t.isAnnotated() || visit(t.type);
4873 }
4874
4875 @Override
4876 public Boolean visitClassType(ClassType t, Void ignore) {
4877 return t.isAnnotated() || visit(t.supertype_field) || visit(t.interfaces_field);
4878 }
4879
4880 @Override
4881 public Boolean visitTypeVar(TypeVar t, Void ignore) {
4882 if (t.isAnnotated())
4883 return true;
4884
4885 if(lock.add(t)) {
4886 try {
4887 return visit(t.bound) || visit(t.lower);
4888 } finally {
4889 lock.remove(t);
4890 }
4891 }
4892
4893 // If we are already looking at this we have completed one cycle and not found any
4894 // annotations.
4895 return false;
4896 }
4897
4898 @Override
4899 public Boolean visitArrayType(ArrayType t, Void ignore) {
4900 if (t.isAnnotated())
4901 return true;
4902 return visit(t.elemtype);
4903 }
4904 }
4905
4906 // </editor-fold>
4907
4908 // <editor-fold defaultstate="collapsed" desc="Signature Generation">
4909
4910 public static abstract class SignatureGenerator {
4911
4912 private final Types types;
4913
4914 protected abstract void append(char ch);
4915 protected abstract void append(byte[] ba);
4916 protected abstract void append(Name name);
4917 protected void classReference(ClassSymbol c) { /* by default: no-op */ }
4918
4919 protected SignatureGenerator(Types types) {
4920 this.types = types;
4921 }
4922
4923 /**
4924 * Assemble signature of given type in string buffer.
4925 */
5060 assembleSig(l.head);
5061 }
5062 }
5063 append('>');
5064 }
5065
5066 private void assembleSig(List<Type> types) {
5067 for (List<Type> ts = types; ts.nonEmpty(); ts = ts.tail) {
5068 assembleSig(ts.head);
5069 }
5070 }
5071 }
5072 // </editor-fold>
5073
5074 public void newRound() {
5075 descCache._map.clear();
5076 isDerivedRawCache.clear();
5077 implCache._map.clear();
5078 membersCache._map.clear();
5079 closureCache.clear();
5080 cachedUnannotated.clear();
5081 }
5082 }
|