32 import java.util.Map;
33 import java.util.Optional;
34 import java.util.Set;
35 import java.util.WeakHashMap;
36 import java.util.function.BiPredicate;
37 import java.util.function.Function;
38 import java.util.function.Predicate;
39 import java.util.stream.Collector;
40
41 import javax.tools.JavaFileObject;
42
43 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
44 import com.sun.tools.javac.code.Lint.LintCategory;
45 import com.sun.tools.javac.code.Source.Feature;
46 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
47 import com.sun.tools.javac.code.TypeMetadata.Entry.Kind;
48 import com.sun.tools.javac.comp.AttrContext;
49 import com.sun.tools.javac.comp.Check;
50 import com.sun.tools.javac.comp.Enter;
51 import com.sun.tools.javac.comp.Env;
52 import com.sun.tools.javac.comp.LambdaToMethod;
53 import com.sun.tools.javac.jvm.ClassFile;
54 import com.sun.tools.javac.util.*;
55
56 import static com.sun.tools.javac.code.BoundKind.*;
57 import static com.sun.tools.javac.code.Flags.*;
58 import static com.sun.tools.javac.code.Kinds.Kind.*;
59 import static com.sun.tools.javac.code.Scope.*;
60 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
61 import static com.sun.tools.javac.code.Symbol.*;
62 import static com.sun.tools.javac.code.Type.*;
63 import static com.sun.tools.javac.code.TypeTag.*;
64 import static com.sun.tools.javac.jvm.ClassFile.externalize;
65 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
66
67 /**
68 * Utility class containing various operations on types.
69 *
70 * <p>Unless other names are more illustrative, the following naming
71 * conventions should be observed in this file:
72 *
75 * <dd>If the first argument to an operation is a type, it should be named t.</dd>
76 * <dt>s</dt>
77 * <dd>Similarly, if the second argument to an operation is a type, it should be named s.</dd>
78 * <dt>ts</dt>
79 * <dd>If an operations takes a list of types, the first should be named ts.</dd>
80 * <dt>ss</dt>
81 * <dd>A second list of types should be named ss.</dd>
82 * </dl>
83 *
84 * <p><b>This is NOT part of any supported API.
85 * If you write code that depends on this, you do so at your own risk.
86 * This code and its internal interfaces are subject to change or
87 * deletion without notice.</b>
88 */
89 public class Types {
90 protected static final Context.Key<Types> typesKey = new Context.Key<>();
91
92 final Symtab syms;
93 final JavacMessages messages;
94 final Names names;
95 final Check chk;
96 final Enter enter;
97 JCDiagnostic.Factory diags;
98 List<Warner> warnStack = List.nil();
99 final Name capturedName;
100
101 public final Warner noWarnings;
102
103 // <editor-fold defaultstate="collapsed" desc="Instantiating">
104 public static Types instance(Context context) {
105 Types instance = context.get(typesKey);
106 if (instance == null)
107 instance = new Types(context);
108 return instance;
109 }
110
111 protected Types(Context context) {
112 context.put(typesKey, this);
113 syms = Symtab.instance(context);
114 names = Names.instance(context);
115 Source source = Source.instance(context);
116 chk = Check.instance(context);
117 enter = Enter.instance(context);
118 capturedName = names.fromString("<captured wildcard>");
119 messages = JavacMessages.instance(context);
120 diags = JCDiagnostic.Factory.instance(context);
121 noWarnings = new Warner(null);
122 qualifiedSymbolCache = new HashMap<>();
123 }
124 // </editor-fold>
125
126 // <editor-fold defaultstate="collapsed" desc="bounds">
127 /**
128 * Get a wildcard's upper bound, returning non-wildcards unchanged.
129 * @param t a type argument, either a wildcard or a type
130 */
131 public Type wildUpperBound(Type t) {
132 if (t.hasTag(WILDCARD)) {
133 WildcardType w = (WildcardType) t;
134 if (w.isSuperBound())
135 return w.bound == null ? syms.objectType : w.bound.getUpperBound();
136 else
137 return wildUpperBound(w.type);
138 }
139 else return t;
140 }
141
251 if (components == components1) return t;
252 else return makeIntersectionType(components1);
253 } else {
254 Type outer = t.getEnclosingType();
255 Type outer1 = visit(outer, pkind);
256 List<Type> typarams = t.getTypeArguments();
257 List<Type> formals = t.tsym.type.getTypeArguments();
258 ListBuffer<Type> typarams1 = new ListBuffer<>();
259 boolean changed = false;
260 for (Type actual : typarams) {
261 Type t2 = mapTypeArgument(t, formals.head.getUpperBound(), actual, pkind);
262 if (t2.hasTag(BOT)) {
263 //not defined
264 return syms.botType;
265 }
266 typarams1.add(t2);
267 changed |= actual != t2;
268 formals = formals.tail;
269 }
270 if (outer1 == outer && !changed) return t;
271 else return new ClassType(outer1, typarams1.toList(), t.tsym, t.getMetadata()) {
272 @Override
273 protected boolean needsStripping() {
274 return true;
275 }
276 };
277 }
278 }
279
280 @Override
281 public Type visitArrayType(ArrayType t, ProjectionKind s) {
282 Type elemtype = t.elemtype;
283 Type elemtype1 = visit(elemtype, s);
284 if (elemtype1 == elemtype) {
285 return t;
286 } else if (elemtype1.hasTag(BOT)) {
287 //undefined
288 return syms.botType;
289 } else {
290 return new ArrayType(elemtype1, t.tsym, t.metadata) {
291 @Override
582 }
583 return res;
584 }
585
586 @Override
587 public Type visitErrorType(ErrorType t, Symbol sym) {
588 return t;
589 }
590 };
591 // </editor-fold>
592
593 // <editor-fold defaultstate="collapsed" desc="isConvertible">
594 /**
595 * Is t a subtype of or convertible via boxing/unboxing
596 * conversion to s?
597 */
598 public boolean isConvertible(Type t, Type s, Warner warn) {
599 if (t.hasTag(ERROR)) {
600 return true;
601 }
602 boolean tPrimitive = t.isPrimitive();
603 boolean sPrimitive = s.isPrimitive();
604 if (tPrimitive == sPrimitive) {
605 return isSubtypeUnchecked(t, s, warn);
606 }
607 boolean tUndet = t.hasTag(UNDETVAR);
608 boolean sUndet = s.hasTag(UNDETVAR);
609
610 if (tUndet || sUndet) {
611 return tUndet ?
612 isSubtype(t, boxedTypeOrType(s)) :
613 isSubtype(boxedTypeOrType(t), s);
614 }
615
616 return tPrimitive
617 ? isSubtype(boxedClass(t).type, s)
618 : isSubtype(unboxedType(t), s);
619 }
620
621 /**
744 Type mtype = memberType(origin.type, sym);
745 if (abstracts.isEmpty()) {
746 abstracts.append(sym);
747 } else if ((sym.name == abstracts.first().name &&
748 overrideEquivalent(mtype, memberType(origin.type, abstracts.first())))) {
749 if (!abstracts.stream().filter(msym -> msym.owner.isSubClass(sym.enclClass(), Types.this))
750 .map(msym -> memberType(origin.type, msym))
751 .anyMatch(abstractMType -> isSubSignature(abstractMType, mtype))) {
752 abstracts.append(sym);
753 }
754 } else {
755 //the target method(s) should be the only abstract members of t
756 throw failure("not.a.functional.intf.1", origin,
757 diags.fragment(Fragments.IncompatibleAbstracts(Kinds.kindName(origin), origin)));
758 }
759 }
760 if (abstracts.isEmpty()) {
761 //t must define a suitable non-generic method
762 throw failure("not.a.functional.intf.1", origin,
763 diags.fragment(Fragments.NoAbstracts(Kinds.kindName(origin), origin)));
764 } else if (abstracts.size() == 1) {
765 return new FunctionDescriptor(abstracts.first());
766 } else { // size > 1
767 FunctionDescriptor descRes = mergeDescriptors(origin, abstracts.toList());
768 if (descRes == null) {
769 //we can get here if the functional interface is ill-formed
770 ListBuffer<JCDiagnostic> descriptors = new ListBuffer<>();
771 for (Symbol desc : abstracts) {
772 String key = desc.type.getThrownTypes().nonEmpty() ?
773 "descriptor.throws" : "descriptor";
774 descriptors.append(diags.fragment(key, desc.name,
775 desc.type.getParameterTypes(),
776 desc.type.getReturnType(),
777 desc.type.getThrownTypes()));
778 }
779 JCDiagnostic msg =
780 diags.fragment(Fragments.IncompatibleDescsInFunctionalIntf(Kinds.kindName(origin),
781 origin));
782 JCDiagnostic.MultilineDiagnostic incompatibleDescriptors =
783 new JCDiagnostic.MultilineDiagnostic(msg, descriptors.toList());
784 throw failure(incompatibleDescriptors);
785 }
786 return descRes;
787 }
788 }
789
790 /**
791 * Compute a synthetic type for the target descriptor given a list
792 * of override-equivalent methods in the functional interface type.
793 * The resulting method type is a method type that is override-equivalent
794 * and return-type substitutable with each method in the original list.
795 */
796 private FunctionDescriptor mergeDescriptors(TypeSymbol origin, List<Symbol> methodSyms) {
797 return mergeAbstracts(methodSyms, origin.type, false)
798 .map(bestSoFar -> new FunctionDescriptor(bestSoFar.baseSymbol()) {
799 @Override
800 public Type getType(Type origin) {
801 Type mt = memberType(origin, getSymbol());
802 return createMethodTypeWithThrown(mt, bestSoFar.type.getThrownTypes());
803 }
804 }).orElse(null);
805 }
806
807 FunctionDescriptorLookupError failure(String msg, Object... args) {
936 else if (descSym.overrides(m2, origin, Types.this, false)) {
937 for (Symbol m3 : overridden) {
938 if (isSameType(m3.erasure(Types.this), m2.erasure(Types.this)) ||
939 (m3.overrides(m2, origin, Types.this, false) &&
940 (pendingBridges((ClassSymbol)origin, m3.enclClass()) ||
941 (((MethodSymbol)m2).binaryImplementation((ClassSymbol)m3.owner, Types.this) != null)))) {
942 continue outer;
943 }
944 }
945 overridden.add(m2);
946 }
947 }
948 return overridden.toList();
949 }
950 //where
951 // Use anonymous class instead of lambda expression intentionally,
952 // because the variable `names` has modifier: final.
953 private Predicate<Symbol> bridgeFilter = new Predicate<Symbol>() {
954 public boolean test(Symbol t) {
955 return t.kind == MTH &&
956 t.name != names.init &&
957 t.name != names.clinit &&
958 (t.flags() & SYNTHETIC) == 0;
959 }
960 };
961
962 private boolean pendingBridges(ClassSymbol origin, TypeSymbol s) {
963 //a symbol will be completed from a classfile if (a) symbol has
964 //an associated file object with CLASS kind and (b) the symbol has
965 //not been entered
966 if (origin.classfile != null &&
967 origin.classfile.getKind() == JavaFileObject.Kind.CLASS &&
968 enter.getEnv(origin) == null) {
969 return false;
970 }
971 if (origin == s) {
972 return true;
973 }
974 for (Type t : interfaces(origin.type)) {
975 if (pendingBridges((ClassSymbol)t.tsym, s)) {
976 return true;
1007 */
1008 public boolean isSubtypeUnchecked(Type t, Type s) {
1009 return isSubtypeUnchecked(t, s, noWarnings);
1010 }
1011 /**
1012 * Is t an unchecked subtype of s?
1013 */
1014 public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) {
1015 boolean result = isSubtypeUncheckedInternal(t, s, true, warn);
1016 if (result) {
1017 checkUnsafeVarargsConversion(t, s, warn);
1018 }
1019 return result;
1020 }
1021 //where
1022 private boolean isSubtypeUncheckedInternal(Type t, Type s, boolean capture, Warner warn) {
1023 if (t.hasTag(ARRAY) && s.hasTag(ARRAY)) {
1024 if (((ArrayType)t).elemtype.isPrimitive()) {
1025 return isSameType(elemtype(t), elemtype(s));
1026 } else {
1027 return isSubtypeUncheckedInternal(elemtype(t), elemtype(s), false, warn);
1028 }
1029 } else if (isSubtype(t, s, capture)) {
1030 return true;
1031 } else if (t.hasTag(TYPEVAR)) {
1032 return isSubtypeUncheckedInternal(t.getUpperBound(), s, false, warn);
1033 } else if (!s.isRaw()) {
1034 Type t2 = asSuper(t, s.tsym);
1035 if (t2 != null && t2.isRaw()) {
1036 if (isReifiable(s)) {
1037 warn.silentWarn(LintCategory.UNCHECKED);
1038 } else {
1039 warn.warn(LintCategory.UNCHECKED);
1040 }
1041 return true;
1042 }
1043 }
1044 return false;
1045 }
1046
1047 private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) {
1104 }
1105 // where
1106 private TypeRelation isSubtype = new TypeRelation()
1107 {
1108 @Override
1109 public Boolean visitType(Type t, Type s) {
1110 switch (t.getTag()) {
1111 case BYTE:
1112 return (!s.hasTag(CHAR) && t.getTag().isSubRangeOf(s.getTag()));
1113 case CHAR:
1114 return (!s.hasTag(SHORT) && t.getTag().isSubRangeOf(s.getTag()));
1115 case SHORT: case INT: case LONG:
1116 case FLOAT: case DOUBLE:
1117 return t.getTag().isSubRangeOf(s.getTag());
1118 case BOOLEAN: case VOID:
1119 return t.hasTag(s.getTag());
1120 case TYPEVAR:
1121 return isSubtypeNoCapture(t.getUpperBound(), s);
1122 case BOT:
1123 return
1124 s.hasTag(BOT) || s.hasTag(CLASS) ||
1125 s.hasTag(ARRAY) || s.hasTag(TYPEVAR);
1126 case WILDCARD: //we shouldn't be here - avoids crash (see 7034495)
1127 case NONE:
1128 return false;
1129 default:
1130 throw new AssertionError("isSubtype " + t.getTag());
1131 }
1132 }
1133
1134 private Set<TypePair> cache = new HashSet<>();
1135
1136 private boolean containsTypeRecursive(Type t, Type s) {
1137 TypePair pair = new TypePair(t, s);
1138 if (cache.add(pair)) {
1139 try {
1140 return containsType(t.getTypeArguments(),
1141 s.getTypeArguments());
1142 } finally {
1143 cache.remove(pair);
1144 }
1171 BoundKind.EXTENDS,
1172 syms.boundClass,
1173 s.getMetadata());
1174 changed = true;
1175 }
1176 rewrite.append(s);
1177 }
1178 if (changed)
1179 return subst(t.tsym.type, from.toList(), rewrite.toList());
1180 else
1181 return t;
1182 }
1183
1184 @Override
1185 public Boolean visitClassType(ClassType t, Type s) {
1186 Type sup = asSuper(t, s.tsym);
1187 if (sup == null) return false;
1188 // If t is an intersection, sup might not be a class type
1189 if (!sup.hasTag(CLASS)) return isSubtypeNoCapture(sup, s);
1190 return sup.tsym == s.tsym
1191 // Check type variable containment
1192 && (!s.isParameterized() || containsTypeRecursive(s, sup))
1193 && isSubtypeNoCapture(sup.getEnclosingType(),
1194 s.getEnclosingType());
1195 }
1196
1197 @Override
1198 public Boolean visitArrayType(ArrayType t, Type s) {
1199 if (s.hasTag(ARRAY)) {
1200 if (t.elemtype.isPrimitive())
1201 return isSameType(t.elemtype, elemtype(s));
1202 else
1203 return isSubtypeNoCapture(t.elemtype, elemtype(s));
1204 }
1205
1206 if (s.hasTag(CLASS)) {
1207 Name sname = s.tsym.getQualifiedName();
1208 return sname == names.java_lang_Object
1209 || sname == names.java_lang_Cloneable
1210 || sname == names.java_io_Serializable;
1211 }
1212
1213 return false;
1214 }
1215
1216 @Override
1217 public Boolean visitUndetVar(UndetVar t, Type s) {
1218 //todo: test against origin needed? or replace with substitution?
1219 if (t == s || t.qtype == s || s.hasTag(ERROR) || s.hasTag(UNKNOWN)) {
1220 return true;
1221 } else if (s.hasTag(BOT)) {
1222 //if 's' is 'null' there's no instantiated type U for which
1223 //U <: s (but 'null' itself, which is not a valid type)
1406 if (!visit(supertype(t), supertype(s)))
1407 return false;
1408
1409 Map<Symbol,Type> tMap = new HashMap<>();
1410 for (Type ti : interfaces(t)) {
1411 if (tMap.containsKey(ti)) {
1412 throw new AssertionError("Malformed intersection");
1413 }
1414 tMap.put(ti.tsym, ti);
1415 }
1416 for (Type si : interfaces(s)) {
1417 if (!tMap.containsKey(si.tsym))
1418 return false;
1419 Type ti = tMap.remove(si.tsym);
1420 if (!visit(ti, si))
1421 return false;
1422 }
1423 return tMap.isEmpty();
1424 }
1425 return t.tsym == s.tsym
1426 && visit(t.getEnclosingType(), s.getEnclosingType())
1427 && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments());
1428 }
1429
1430 @Override
1431 public Boolean visitArrayType(ArrayType t, Type s) {
1432 if (t == s)
1433 return true;
1434
1435 if (s.isPartial())
1436 return visit(s, t);
1437
1438 return s.hasTag(ARRAY)
1439 && containsTypeEquivalent(t.elemtype, elemtype(s));
1440 }
1441
1442 @Override
1443 public Boolean visitMethodType(MethodType t, Type s) {
1444 // isSameType for methods does not take thrown
1445 // exceptions into account!
1446 return hasSameArgs(t, s) && visit(t.getReturnType(), s.getReturnType());
1447 }
1448
1568 // void debugContainsType(WildcardType t, Type s) {
1569 // System.err.println();
1570 // System.err.format(" does %s contain %s?%n", t, s);
1571 // System.err.format(" %s U(%s) <: U(%s) %s = %s%n",
1572 // wildUpperBound(s), s, t, wildUpperBound(t),
1573 // t.isSuperBound()
1574 // || isSubtypeNoCapture(wildUpperBound(s), wildUpperBound(t)));
1575 // System.err.format(" %s L(%s) <: L(%s) %s = %s%n",
1576 // wildLowerBound(t), t, s, wildLowerBound(s),
1577 // t.isExtendsBound()
1578 // || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s)));
1579 // System.err.println();
1580 // }
1581
1582 @Override
1583 public Boolean visitWildcardType(WildcardType t, Type s) {
1584 if (s.isPartial())
1585 return containedBy(s, t);
1586 else {
1587 // debugContainsType(t, s);
1588 return isSameWildcard(t, s)
1589 || isCaptureOf(s, t)
1590 || ((t.isExtendsBound() || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s))) &&
1591 (t.isSuperBound() || isSubtypeNoCapture(wildUpperBound(s), wildUpperBound(t))));
1592 }
1593 }
1594
1595 @Override
1596 public Boolean visitUndetVar(UndetVar t, Type s) {
1597 if (!s.hasTag(WILDCARD)) {
1598 return isSameType(t, s);
1599 } else {
1600 return false;
1601 }
1602 }
1603
1604 @Override
1605 public Boolean visitErrorType(ErrorType t, Type s) {
1606 return true;
1607 }
1657 warnStack = warnStack.prepend(warn);
1658 checkUnsafeVarargsConversion(t, s, warn);
1659 result = isCastable.visit(t,s);
1660 } finally {
1661 warnStack = warnStack.tail;
1662 }
1663 } else {
1664 result = isCastable.visit(t,s);
1665 }
1666 if (result && t.hasTag(CLASS) && t.tsym.kind.matches(Kinds.KindSelector.TYP)
1667 && s.hasTag(CLASS) && s.tsym.kind.matches(Kinds.KindSelector.TYP)
1668 && (t.tsym.isSealed() || s.tsym.isSealed())) {
1669 return (t.isCompound() || s.isCompound()) ?
1670 true :
1671 !areDisjoint((ClassSymbol)t.tsym, (ClassSymbol)s.tsym);
1672 }
1673 return result;
1674 }
1675 // where
1676 private boolean areDisjoint(ClassSymbol ts, ClassSymbol ss) {
1677 if (isSubtype(erasure(ts.type), erasure(ss.type))) {
1678 return false;
1679 }
1680 // if both are classes or both are interfaces, shortcut
1681 if (ts.isInterface() == ss.isInterface() && isSubtype(erasure(ss.type), erasure(ts.type))) {
1682 return false;
1683 }
1684 if (ts.isInterface() && !ss.isInterface()) {
1685 /* so ts is interface but ss is a class
1686 * an interface is disjoint from a class if the class is disjoint form the interface
1687 */
1688 return areDisjoint(ss, ts);
1689 }
1690 // a final class that is not subtype of ss is disjoint
1691 if (!ts.isInterface() && ts.isFinal()) {
1692 return true;
1693 }
1694 // if at least one is sealed
1695 if (ts.isSealed() || ss.isSealed()) {
1696 // permitted subtypes have to be disjoint with the other symbol
1697 ClassSymbol sealedOne = ts.isSealed() ? ts : ss;
1712 case DOUBLE:
1713 return s.isNumeric();
1714 case BOOLEAN:
1715 return s.hasTag(BOOLEAN);
1716 case VOID:
1717 return false;
1718 case BOT:
1719 return isSubtype(t, s);
1720 default:
1721 throw new AssertionError();
1722 }
1723 }
1724
1725 @Override
1726 public Boolean visitWildcardType(WildcardType t, Type s) {
1727 return isCastable(wildUpperBound(t), s, warnStack.head);
1728 }
1729
1730 @Override
1731 public Boolean visitClassType(ClassType t, Type s) {
1732 if (s.hasTag(ERROR) || s.hasTag(BOT))
1733 return true;
1734
1735 if (s.hasTag(TYPEVAR)) {
1736 if (isCastable(t, s.getUpperBound(), noWarnings)) {
1737 warnStack.head.warn(LintCategory.UNCHECKED);
1738 return true;
1739 } else {
1740 return false;
1741 }
1742 }
1743
1744 if (t.isCompound() || s.isCompound()) {
1745 return !t.isCompound() ?
1746 visitCompoundType((ClassType)s, t, true) :
1747 visitCompoundType(t, s, false);
1748 }
1749
1750 if (s.hasTag(CLASS) || s.hasTag(ARRAY)) {
1751 boolean upcast;
1752 if ((upcast = isSubtype(erasure(t), erasure(s)))
1753 || isSubtype(erasure(s), erasure(t))) {
1754 if (!upcast && s.hasTag(ARRAY)) {
1755 if (!isReifiable(s))
1756 warnStack.head.warn(LintCategory.UNCHECKED);
1757 return true;
1758 } else if (s.isRaw()) {
1759 return true;
1760 } else if (t.isRaw()) {
1761 if (!isUnbounded(s))
1762 warnStack.head.warn(LintCategory.UNCHECKED);
1763 return true;
1764 }
1765 // Assume |a| <: |b|
1766 final Type a = upcast ? t : s;
1767 final Type b = upcast ? s : t;
1768 final boolean HIGH = true;
1769 final boolean LOW = false;
1770 final boolean DONT_REWRITE_TYPEVARS = false;
2124 * @return the ArrayType for the given component
2125 */
2126 public ArrayType makeArrayType(Type t) {
2127 if (t.hasTag(VOID) || t.hasTag(PACKAGE)) {
2128 Assert.error("Type t must not be a VOID or PACKAGE type, " + t.toString());
2129 }
2130 return new ArrayType(t, syms.arrayClass);
2131 }
2132 // </editor-fold>
2133
2134 // <editor-fold defaultstate="collapsed" desc="asSuper">
2135 /**
2136 * Return the (most specific) base type of t that starts with the
2137 * given symbol. If none exists, return null.
2138 *
2139 * Caveat Emptor: Since javac represents the class of all arrays with a singleton
2140 * symbol Symtab.arrayClass, which by being a singleton cannot hold any discriminant,
2141 * this method could yield surprising answers when invoked on arrays. For example when
2142 * invoked with t being byte [] and sym being t.sym itself, asSuper would answer null.
2143 *
2144 * @param t a type
2145 * @param sym a symbol
2146 */
2147 public Type asSuper(Type t, Symbol sym) {
2148 /* Some examples:
2149 *
2150 * (Enum<E>, Comparable) => Comparable<E>
2151 * (c.s.s.d.AttributeTree.ValueKind, Enum) => Enum<c.s.s.d.AttributeTree.ValueKind>
2152 * (c.s.s.t.ExpressionTree, c.s.s.t.Tree) => c.s.s.t.Tree
2153 * (j.u.List<capture#160 of ? extends c.s.s.d.DocTree>, Iterable) =>
2154 * Iterable<capture#160 of ? extends c.s.s.d.DocTree>
2155 */
2156 if (sym.type == syms.objectType) { //optimization
2157 return syms.objectType;
2158 }
2159 return asSuper.visit(t, sym);
2160 }
2161 // where
2162 private SimpleVisitor<Type,Symbol> asSuper = new SimpleVisitor<Type,Symbol>() {
2163
2164 private Set<Symbol> seenTypes = new HashSet<>();
2165
2166 public Type visitType(Type t, Symbol sym) {
2167 return null;
2168 }
2169
2170 @Override
2171 public Type visitClassType(ClassType t, Symbol sym) {
2172 if (t.tsym == sym)
2173 return t;
2174
2175 Symbol c = t.tsym;
2266 case ARRAY:
2267 return isSubtype(t, sym.type) ? sym.type : null;
2268 case TYPEVAR:
2269 return asSuper(t, sym);
2270 case ERROR:
2271 return t;
2272 default:
2273 return null;
2274 }
2275 }
2276 // </editor-fold>
2277
2278 // <editor-fold defaultstate="collapsed" desc="memberType">
2279 /**
2280 * The type of given symbol, seen as a member of t.
2281 *
2282 * @param t a type
2283 * @param sym a symbol
2284 */
2285 public Type memberType(Type t, Symbol sym) {
2286 return (sym.flags() & STATIC) != 0
2287 ? sym.type
2288 : memberType.visit(t, sym);
2289 }
2290 // where
2291 private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
2292
2293 public Type visitType(Type t, Symbol sym) {
2294 return sym.type;
2295 }
2296
2297 @Override
2298 public Type visitWildcardType(WildcardType t, Symbol sym) {
2299 return memberType(wildUpperBound(t), sym);
2300 }
2301
2302 @Override
2303 public Type visitClassType(ClassType t, Symbol sym) {
2304 Symbol owner = sym.owner;
2305 long flags = sym.flags();
2306 if (((flags & STATIC) == 0) && owner.type.isParameterized()) {
2307 Type base = asOuterSuper(t, owner);
2308 //if t is an intersection type T = CT & I1 & I2 ... & In
2421 }
2422 }
2423
2424 public Type visitType(Type t, Boolean recurse) {
2425 if (t.isPrimitive())
2426 return t; /*fast special case*/
2427 else {
2428 //other cases already handled
2429 return combineMetadata(t, t);
2430 }
2431 }
2432
2433 @Override
2434 public Type visitWildcardType(WildcardType t, Boolean recurse) {
2435 Type erased = erasure(wildUpperBound(t), recurse);
2436 return combineMetadata(erased, t);
2437 }
2438
2439 @Override
2440 public Type visitClassType(ClassType t, Boolean recurse) {
2441 Type erased = t.tsym.erasure(Types.this);
2442 if (recurse) {
2443 erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym,
2444 t.getMetadata().without(Kind.ANNOTATIONS));
2445 return erased;
2446 } else {
2447 return combineMetadata(erased, t);
2448 }
2449 }
2450
2451 @Override
2452 public Type visitTypeVar(TypeVar t, Boolean recurse) {
2453 Type erased = erasure(t.getUpperBound(), recurse);
2454 return combineMetadata(erased, t);
2455 }
2456 };
2457
2458 public List<Type> erasure(List<Type> ts) {
2459 return erasure.visit(ts, false);
2460 }
2461
2462 public Type erasureRecursive(Type t) {
2463 return erasure(t, true);
2464 }
2465
2466 public List<Type> erasureRecursive(List<Type> ts) {
2467 return erasure.visit(ts, true);
2468 }
2469 // </editor-fold>
2749 /**
2750 * If the given type is a (possibly selected) type variable,
2751 * return the bounding class of this type, otherwise return the
2752 * type itself.
2753 */
2754 public Type classBound(Type t) {
2755 return classBound.visit(t);
2756 }
2757 // where
2758 private UnaryVisitor<Type> classBound = new UnaryVisitor<Type>() {
2759
2760 public Type visitType(Type t, Void ignored) {
2761 return t;
2762 }
2763
2764 @Override
2765 public Type visitClassType(ClassType t, Void ignored) {
2766 Type outer1 = classBound(t.getEnclosingType());
2767 if (outer1 != t.getEnclosingType())
2768 return new ClassType(outer1, t.getTypeArguments(), t.tsym,
2769 t.getMetadata());
2770 else
2771 return t;
2772 }
2773
2774 @Override
2775 public Type visitTypeVar(TypeVar t, Void ignored) {
2776 return classBound(supertype(t));
2777 }
2778
2779 @Override
2780 public Type visitErrorType(ErrorType t, Void ignored) {
2781 return t;
2782 }
2783 };
2784 // </editor-fold>
2785
2786 // <editor-fold defaultstate="collapsed" desc="subsignature / override equivalence">
2787 /**
2788 * Returns true iff the first signature is a <em>subsignature</em>
2789 * of the other. This is <b>not</b> an equivalence
3920 m = new WildcardType(lub(wildUpperBound(act1.head),
3921 wildUpperBound(act2.head)),
3922 BoundKind.EXTENDS,
3923 syms.boundClass);
3924 mergeCache.remove(pair);
3925 } else {
3926 m = new WildcardType(syms.objectType,
3927 BoundKind.UNBOUND,
3928 syms.boundClass);
3929 }
3930 merged.append(m.withTypeVar(typarams.head));
3931 }
3932 act1 = act1.tail;
3933 act2 = act2.tail;
3934 typarams = typarams.tail;
3935 }
3936 Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
3937 // There is no spec detailing how type annotations are to
3938 // be inherited. So set it to noAnnotations for now
3939 return new ClassType(class1.getEnclosingType(), merged.toList(),
3940 class1.tsym);
3941 }
3942
3943 /**
3944 * Return the minimum type of a closure, a compound type if no
3945 * unique minimum exists.
3946 */
3947 private Type compoundMin(List<Type> cl) {
3948 if (cl.isEmpty()) return syms.objectType;
3949 List<Type> compound = closureMin(cl);
3950 if (compound.isEmpty())
3951 return null;
3952 else if (compound.tail.isEmpty())
3953 return compound.head;
3954 else
3955 return makeIntersectionType(compound);
3956 }
3957
3958 /**
3959 * Return the minimum types of a closure, suitable for computing
3960 * compoundMin or glb.
4480 Si.lower = Ti.getSuperBound();
4481 break;
4482 }
4483 Type tmpBound = Si.getUpperBound().hasTag(UNDETVAR) ? ((UndetVar)Si.getUpperBound()).qtype : Si.getUpperBound();
4484 Type tmpLower = Si.lower.hasTag(UNDETVAR) ? ((UndetVar)Si.lower).qtype : Si.lower;
4485 if (!Si.getUpperBound().hasTag(ERROR) &&
4486 !Si.lower.hasTag(ERROR) &&
4487 isSameType(tmpBound, tmpLower)) {
4488 currentS.head = Si.getUpperBound();
4489 }
4490 }
4491 currentA = currentA.tail;
4492 currentT = currentT.tail;
4493 currentS = currentS.tail;
4494 }
4495 if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty())
4496 return erasure(t); // some "rare" type involved
4497
4498 if (captured)
4499 return new ClassType(cls.getEnclosingType(), S, cls.tsym,
4500 cls.getMetadata());
4501 else
4502 return t;
4503 }
4504 // where
4505 public List<Type> freshTypeVariables(List<Type> types) {
4506 ListBuffer<Type> result = new ListBuffer<>();
4507 for (Type t : types) {
4508 if (t.hasTag(WILDCARD)) {
4509 Type bound = ((WildcardType)t).getExtendsBound();
4510 if (bound == null)
4511 bound = syms.objectType;
4512 result.append(new CapturedType(capturedName,
4513 syms.noSymbol,
4514 bound,
4515 syms.botType,
4516 (WildcardType)t));
4517 } else {
4518 result.append(t);
4519 }
4520 }
4891 private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
4892 if (bound.hasTag(BOT)) {
4893 return new WildcardType(syms.objectType,
4894 BoundKind.UNBOUND,
4895 syms.boundClass,
4896 formal);
4897 } else {
4898 return new WildcardType(bound,
4899 BoundKind.SUPER,
4900 syms.boundClass,
4901 formal);
4902 }
4903 }
4904
4905 /**
4906 * A wrapper for a type that allows use in sets.
4907 */
4908 public static class UniqueType {
4909 public final Type type;
4910 final Types types;
4911
4912 public UniqueType(Type type, Types types) {
4913 this.type = type;
4914 this.types = types;
4915 }
4916
4917 public int hashCode() {
4918 return types.hashCode(type);
4919 }
4920
4921 public boolean equals(Object obj) {
4922 return (obj instanceof UniqueType uniqueType) &&
4923 types.isSameType(type, uniqueType.type);
4924 }
4925
4926 public String toString() {
4927 return type.toString();
4928 }
4929
4930 }
4931 // </editor-fold>
4932
4933 // <editor-fold defaultstate="collapsed" desc="Visitors">
4934 /**
4935 * A default visitor for types. All visitor methods except
4936 * visitType are implemented by delegating to visitType. Concrete
4937 * subclasses must provide an implementation of visitType and can
4938 * override other methods as needed.
4939 *
4940 * @param <R> the return type of the operation implemented by this
4941 * visitor; use Void if no return type is needed.
4942 * @param <S> the type of the second argument (the first being the
4943 * type itself) of the operation implemented by this visitor; use
4944 * Void if a second argument is not needed.
4945 */
5144 break;
5145 case LONG:
5146 append('J');
5147 break;
5148 case FLOAT:
5149 append('F');
5150 break;
5151 case DOUBLE:
5152 append('D');
5153 break;
5154 case BOOLEAN:
5155 append('Z');
5156 break;
5157 case VOID:
5158 append('V');
5159 break;
5160 case CLASS:
5161 if (type.isCompound()) {
5162 reportIllegalSignature(type);
5163 }
5164 append('L');
5165 assembleClassSig(type);
5166 append(';');
5167 break;
5168 case ARRAY:
5169 ArrayType at = (ArrayType) type;
5170 append('[');
5171 assembleSig(at.elemtype);
5172 break;
5173 case METHOD:
5174 MethodType mt = (MethodType) type;
5175 append('(');
5176 assembleSig(mt.argtypes);
5177 append(')');
5178 assembleSig(mt.restype);
5179 if (hasTypeVar(mt.thrown)) {
5180 for (List<Type> l = mt.thrown; l.nonEmpty(); l = l.tail) {
5181 append('^');
5182 assembleSig(l.head);
5183 }
5184 }
|
32 import java.util.Map;
33 import java.util.Optional;
34 import java.util.Set;
35 import java.util.WeakHashMap;
36 import java.util.function.BiPredicate;
37 import java.util.function.Function;
38 import java.util.function.Predicate;
39 import java.util.stream.Collector;
40
41 import javax.tools.JavaFileObject;
42
43 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
44 import com.sun.tools.javac.code.Lint.LintCategory;
45 import com.sun.tools.javac.code.Source.Feature;
46 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
47 import com.sun.tools.javac.code.TypeMetadata.Entry.Kind;
48 import com.sun.tools.javac.comp.AttrContext;
49 import com.sun.tools.javac.comp.Check;
50 import com.sun.tools.javac.comp.Enter;
51 import com.sun.tools.javac.comp.Env;
52 import com.sun.tools.javac.jvm.ClassFile;
53 import com.sun.tools.javac.util.*;
54
55 import static com.sun.tools.javac.code.BoundKind.*;
56 import static com.sun.tools.javac.code.Flags.*;
57 import static com.sun.tools.javac.code.Kinds.Kind.*;
58 import static com.sun.tools.javac.code.Scope.*;
59 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
60 import static com.sun.tools.javac.code.Symbol.*;
61 import static com.sun.tools.javac.code.Type.*;
62 import static com.sun.tools.javac.code.TypeTag.*;
63 import static com.sun.tools.javac.jvm.ClassFile.externalize;
64 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
65
66 /**
67 * Utility class containing various operations on types.
68 *
69 * <p>Unless other names are more illustrative, the following naming
70 * conventions should be observed in this file:
71 *
74 * <dd>If the first argument to an operation is a type, it should be named t.</dd>
75 * <dt>s</dt>
76 * <dd>Similarly, if the second argument to an operation is a type, it should be named s.</dd>
77 * <dt>ts</dt>
78 * <dd>If an operations takes a list of types, the first should be named ts.</dd>
79 * <dt>ss</dt>
80 * <dd>A second list of types should be named ss.</dd>
81 * </dl>
82 *
83 * <p><b>This is NOT part of any supported API.
84 * If you write code that depends on this, you do so at your own risk.
85 * This code and its internal interfaces are subject to change or
86 * deletion without notice.</b>
87 */
88 public class Types {
89 protected static final Context.Key<Types> typesKey = new Context.Key<>();
90
91 final Symtab syms;
92 final JavacMessages messages;
93 final Names names;
94 final boolean allowPrimitiveClasses;
95 final Check chk;
96 final Enter enter;
97 JCDiagnostic.Factory diags;
98 List<Warner> warnStack = List.nil();
99 final Name capturedName;
100
101 public final Warner noWarnings;
102
103 // <editor-fold defaultstate="collapsed" desc="Instantiating">
104 public static Types instance(Context context) {
105 Types instance = context.get(typesKey);
106 if (instance == null)
107 instance = new Types(context);
108 return instance;
109 }
110
111 protected Types(Context context) {
112 context.put(typesKey, this);
113 syms = Symtab.instance(context);
114 names = Names.instance(context);
115 Source source = Source.instance(context);
116 chk = Check.instance(context);
117 enter = Enter.instance(context);
118 capturedName = names.fromString("<captured wildcard>");
119 messages = JavacMessages.instance(context);
120 diags = JCDiagnostic.Factory.instance(context);
121 noWarnings = new Warner(null);
122 Options options = Options.instance(context);
123 allowPrimitiveClasses = Feature.PRIMITIVE_CLASSES.allowedInSource(source) && options.isSet("enablePrimitiveClasses");
124 qualifiedSymbolCache = new HashMap<>();
125 }
126 // </editor-fold>
127
128 // <editor-fold defaultstate="collapsed" desc="bounds">
129 /**
130 * Get a wildcard's upper bound, returning non-wildcards unchanged.
131 * @param t a type argument, either a wildcard or a type
132 */
133 public Type wildUpperBound(Type t) {
134 if (t.hasTag(WILDCARD)) {
135 WildcardType w = (WildcardType) t;
136 if (w.isSuperBound())
137 return w.bound == null ? syms.objectType : w.bound.getUpperBound();
138 else
139 return wildUpperBound(w.type);
140 }
141 else return t;
142 }
143
253 if (components == components1) return t;
254 else return makeIntersectionType(components1);
255 } else {
256 Type outer = t.getEnclosingType();
257 Type outer1 = visit(outer, pkind);
258 List<Type> typarams = t.getTypeArguments();
259 List<Type> formals = t.tsym.type.getTypeArguments();
260 ListBuffer<Type> typarams1 = new ListBuffer<>();
261 boolean changed = false;
262 for (Type actual : typarams) {
263 Type t2 = mapTypeArgument(t, formals.head.getUpperBound(), actual, pkind);
264 if (t2.hasTag(BOT)) {
265 //not defined
266 return syms.botType;
267 }
268 typarams1.add(t2);
269 changed |= actual != t2;
270 formals = formals.tail;
271 }
272 if (outer1 == outer && !changed) return t;
273 else return new ClassType(outer1, typarams1.toList(), t.tsym, t.getMetadata(), t.getFlavor()) {
274 @Override
275 protected boolean needsStripping() {
276 return true;
277 }
278 };
279 }
280 }
281
282 @Override
283 public Type visitArrayType(ArrayType t, ProjectionKind s) {
284 Type elemtype = t.elemtype;
285 Type elemtype1 = visit(elemtype, s);
286 if (elemtype1 == elemtype) {
287 return t;
288 } else if (elemtype1.hasTag(BOT)) {
289 //undefined
290 return syms.botType;
291 } else {
292 return new ArrayType(elemtype1, t.tsym, t.metadata) {
293 @Override
584 }
585 return res;
586 }
587
588 @Override
589 public Type visitErrorType(ErrorType t, Symbol sym) {
590 return t;
591 }
592 };
593 // </editor-fold>
594
595 // <editor-fold defaultstate="collapsed" desc="isConvertible">
596 /**
597 * Is t a subtype of or convertible via boxing/unboxing
598 * conversion to s?
599 */
600 public boolean isConvertible(Type t, Type s, Warner warn) {
601 if (t.hasTag(ERROR)) {
602 return true;
603 }
604
605 if (allowPrimitiveClasses) {
606 boolean tValue = t.isPrimitiveClass();
607 boolean sValue = s.isPrimitiveClass();
608 if (tValue != sValue) {
609 return tValue ?
610 isSubtype(t.referenceProjection(), s) :
611 !t.hasTag(BOT) && isSubtype(t, s.referenceProjection());
612 }
613 }
614
615 boolean tPrimitive = t.isPrimitive();
616 boolean sPrimitive = s.isPrimitive();
617 if (tPrimitive == sPrimitive) {
618 return isSubtypeUnchecked(t, s, warn);
619 }
620 boolean tUndet = t.hasTag(UNDETVAR);
621 boolean sUndet = s.hasTag(UNDETVAR);
622
623 if (tUndet || sUndet) {
624 return tUndet ?
625 isSubtype(t, boxedTypeOrType(s)) :
626 isSubtype(boxedTypeOrType(t), s);
627 }
628
629 return tPrimitive
630 ? isSubtype(boxedClass(t).type, s)
631 : isSubtype(unboxedType(t), s);
632 }
633
634 /**
757 Type mtype = memberType(origin.type, sym);
758 if (abstracts.isEmpty()) {
759 abstracts.append(sym);
760 } else if ((sym.name == abstracts.first().name &&
761 overrideEquivalent(mtype, memberType(origin.type, abstracts.first())))) {
762 if (!abstracts.stream().filter(msym -> msym.owner.isSubClass(sym.enclClass(), Types.this))
763 .map(msym -> memberType(origin.type, msym))
764 .anyMatch(abstractMType -> isSubSignature(abstractMType, mtype))) {
765 abstracts.append(sym);
766 }
767 } else {
768 //the target method(s) should be the only abstract members of t
769 throw failure("not.a.functional.intf.1", origin,
770 diags.fragment(Fragments.IncompatibleAbstracts(Kinds.kindName(origin), origin)));
771 }
772 }
773 if (abstracts.isEmpty()) {
774 //t must define a suitable non-generic method
775 throw failure("not.a.functional.intf.1", origin,
776 diags.fragment(Fragments.NoAbstracts(Kinds.kindName(origin), origin)));
777 }
778 FunctionDescriptor descRes;
779 if (abstracts.size() == 1) {
780 descRes = new FunctionDescriptor(abstracts.first());
781 } else { // size > 1
782 descRes = mergeDescriptors(origin, abstracts.toList());
783 if (descRes == null) {
784 //we can get here if the functional interface is ill-formed
785 ListBuffer<JCDiagnostic> descriptors = new ListBuffer<>();
786 for (Symbol desc : abstracts) {
787 String key = desc.type.getThrownTypes().nonEmpty() ?
788 "descriptor.throws" : "descriptor";
789 descriptors.append(diags.fragment(key, desc.name,
790 desc.type.getParameterTypes(),
791 desc.type.getReturnType(),
792 desc.type.getThrownTypes()));
793 }
794 JCDiagnostic msg =
795 diags.fragment(Fragments.IncompatibleDescsInFunctionalIntf(Kinds.kindName(origin),
796 origin));
797 JCDiagnostic.MultilineDiagnostic incompatibleDescriptors =
798 new JCDiagnostic.MultilineDiagnostic(msg, descriptors.toList());
799 throw failure(incompatibleDescriptors);
800 }
801 }
802 // an interface must be neither an identity interface nor a value interface to be functional.
803 List<Type> allInterfaces = closure(origin.type);
804 for (Type iface : allInterfaces) {
805 if (iface.isValueInterface()) {
806 throw failure("not.a.functional.intf.1", origin, diags.fragment(Fragments.ValueInterfaceNonfunctional));
807 }
808 if (iface.isIdentityInterface()) {
809 throw failure("not.a.functional.intf.1", origin, diags.fragment(Fragments.IdentityInterfaceNonfunctional));
810 }
811 }
812 return descRes;
813 }
814
815 /**
816 * Compute a synthetic type for the target descriptor given a list
817 * of override-equivalent methods in the functional interface type.
818 * The resulting method type is a method type that is override-equivalent
819 * and return-type substitutable with each method in the original list.
820 */
821 private FunctionDescriptor mergeDescriptors(TypeSymbol origin, List<Symbol> methodSyms) {
822 return mergeAbstracts(methodSyms, origin.type, false)
823 .map(bestSoFar -> new FunctionDescriptor(bestSoFar.baseSymbol()) {
824 @Override
825 public Type getType(Type origin) {
826 Type mt = memberType(origin, getSymbol());
827 return createMethodTypeWithThrown(mt, bestSoFar.type.getThrownTypes());
828 }
829 }).orElse(null);
830 }
831
832 FunctionDescriptorLookupError failure(String msg, Object... args) {
961 else if (descSym.overrides(m2, origin, Types.this, false)) {
962 for (Symbol m3 : overridden) {
963 if (isSameType(m3.erasure(Types.this), m2.erasure(Types.this)) ||
964 (m3.overrides(m2, origin, Types.this, false) &&
965 (pendingBridges((ClassSymbol)origin, m3.enclClass()) ||
966 (((MethodSymbol)m2).binaryImplementation((ClassSymbol)m3.owner, Types.this) != null)))) {
967 continue outer;
968 }
969 }
970 overridden.add(m2);
971 }
972 }
973 return overridden.toList();
974 }
975 //where
976 // Use anonymous class instead of lambda expression intentionally,
977 // because the variable `names` has modifier: final.
978 private Predicate<Symbol> bridgeFilter = new Predicate<Symbol>() {
979 public boolean test(Symbol t) {
980 return t.kind == MTH &&
981 !names.isInitOrVNew(t.name) &&
982 t.name != names.clinit &&
983 (t.flags() & SYNTHETIC) == 0;
984 }
985 };
986
987 private boolean pendingBridges(ClassSymbol origin, TypeSymbol s) {
988 //a symbol will be completed from a classfile if (a) symbol has
989 //an associated file object with CLASS kind and (b) the symbol has
990 //not been entered
991 if (origin.classfile != null &&
992 origin.classfile.getKind() == JavaFileObject.Kind.CLASS &&
993 enter.getEnv(origin) == null) {
994 return false;
995 }
996 if (origin == s) {
997 return true;
998 }
999 for (Type t : interfaces(origin.type)) {
1000 if (pendingBridges((ClassSymbol)t.tsym, s)) {
1001 return true;
1032 */
1033 public boolean isSubtypeUnchecked(Type t, Type s) {
1034 return isSubtypeUnchecked(t, s, noWarnings);
1035 }
1036 /**
1037 * Is t an unchecked subtype of s?
1038 */
1039 public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) {
1040 boolean result = isSubtypeUncheckedInternal(t, s, true, warn);
1041 if (result) {
1042 checkUnsafeVarargsConversion(t, s, warn);
1043 }
1044 return result;
1045 }
1046 //where
1047 private boolean isSubtypeUncheckedInternal(Type t, Type s, boolean capture, Warner warn) {
1048 if (t.hasTag(ARRAY) && s.hasTag(ARRAY)) {
1049 if (((ArrayType)t).elemtype.isPrimitive()) {
1050 return isSameType(elemtype(t), elemtype(s));
1051 } else {
1052 // if T.ref <: S, then T[] <: S[]
1053 Type es = elemtype(s);
1054 Type et = elemtype(t);
1055 if (allowPrimitiveClasses) {
1056 if (et.isPrimitiveClass()) {
1057 et = et.referenceProjection();
1058 if (es.isPrimitiveClass())
1059 es = es.referenceProjection(); // V <: V, surely
1060 }
1061 }
1062 if (!isSubtypeUncheckedInternal(et, es, false, warn))
1063 return false;
1064 return true;
1065 }
1066 } else if (isSubtype(t, s, capture)) {
1067 return true;
1068 } else if (t.hasTag(TYPEVAR)) {
1069 return isSubtypeUncheckedInternal(t.getUpperBound(), s, false, warn);
1070 } else if (!s.isRaw()) {
1071 Type t2 = asSuper(t, s.tsym);
1072 if (t2 != null && t2.isRaw()) {
1073 if (isReifiable(s)) {
1074 warn.silentWarn(LintCategory.UNCHECKED);
1075 } else {
1076 warn.warn(LintCategory.UNCHECKED);
1077 }
1078 return true;
1079 }
1080 }
1081 return false;
1082 }
1083
1084 private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) {
1141 }
1142 // where
1143 private TypeRelation isSubtype = new TypeRelation()
1144 {
1145 @Override
1146 public Boolean visitType(Type t, Type s) {
1147 switch (t.getTag()) {
1148 case BYTE:
1149 return (!s.hasTag(CHAR) && t.getTag().isSubRangeOf(s.getTag()));
1150 case CHAR:
1151 return (!s.hasTag(SHORT) && t.getTag().isSubRangeOf(s.getTag()));
1152 case SHORT: case INT: case LONG:
1153 case FLOAT: case DOUBLE:
1154 return t.getTag().isSubRangeOf(s.getTag());
1155 case BOOLEAN: case VOID:
1156 return t.hasTag(s.getTag());
1157 case TYPEVAR:
1158 return isSubtypeNoCapture(t.getUpperBound(), s);
1159 case BOT:
1160 return
1161 s.hasTag(BOT) || (s.hasTag(CLASS) && (!allowPrimitiveClasses || !s.isPrimitiveClass())) ||
1162 s.hasTag(ARRAY) || s.hasTag(TYPEVAR);
1163 case WILDCARD: //we shouldn't be here - avoids crash (see 7034495)
1164 case NONE:
1165 return false;
1166 default:
1167 throw new AssertionError("isSubtype " + t.getTag());
1168 }
1169 }
1170
1171 private Set<TypePair> cache = new HashSet<>();
1172
1173 private boolean containsTypeRecursive(Type t, Type s) {
1174 TypePair pair = new TypePair(t, s);
1175 if (cache.add(pair)) {
1176 try {
1177 return containsType(t.getTypeArguments(),
1178 s.getTypeArguments());
1179 } finally {
1180 cache.remove(pair);
1181 }
1208 BoundKind.EXTENDS,
1209 syms.boundClass,
1210 s.getMetadata());
1211 changed = true;
1212 }
1213 rewrite.append(s);
1214 }
1215 if (changed)
1216 return subst(t.tsym.type, from.toList(), rewrite.toList());
1217 else
1218 return t;
1219 }
1220
1221 @Override
1222 public Boolean visitClassType(ClassType t, Type s) {
1223 Type sup = asSuper(t, s.tsym);
1224 if (sup == null) return false;
1225 // If t is an intersection, sup might not be a class type
1226 if (!sup.hasTag(CLASS)) return isSubtypeNoCapture(sup, s);
1227 return sup.tsym == s.tsym
1228 && (t.tsym != s.tsym || t.isReferenceProjection() == s.isReferenceProjection())
1229 // Check type variable containment
1230 && (!s.isParameterized() || containsTypeRecursive(s, sup))
1231 && isSubtypeNoCapture(sup.getEnclosingType(),
1232 s.getEnclosingType());
1233 }
1234
1235 @Override
1236 public Boolean visitArrayType(ArrayType t, Type s) {
1237 if (s.hasTag(ARRAY)) {
1238 if (t.elemtype.isPrimitive())
1239 return isSameType(t.elemtype, elemtype(s));
1240 else {
1241 // if T.ref <: S, then T[] <: S[]
1242 Type es = elemtype(s);
1243 Type et = elemtype(t);
1244 if (allowPrimitiveClasses && et.isPrimitiveClass()) {
1245 et = et.referenceProjection();
1246 if (es.isPrimitiveClass())
1247 es = es.referenceProjection(); // V <: V, surely
1248 }
1249 return isSubtypeNoCapture(et, es);
1250 }
1251 }
1252
1253 if (s.hasTag(CLASS)) {
1254 Name sname = s.tsym.getQualifiedName();
1255 return sname == names.java_lang_Object
1256 || sname == names.java_lang_Cloneable
1257 || sname == names.java_io_Serializable;
1258 }
1259
1260 return false;
1261 }
1262
1263 @Override
1264 public Boolean visitUndetVar(UndetVar t, Type s) {
1265 //todo: test against origin needed? or replace with substitution?
1266 if (t == s || t.qtype == s || s.hasTag(ERROR) || s.hasTag(UNKNOWN)) {
1267 return true;
1268 } else if (s.hasTag(BOT)) {
1269 //if 's' is 'null' there's no instantiated type U for which
1270 //U <: s (but 'null' itself, which is not a valid type)
1453 if (!visit(supertype(t), supertype(s)))
1454 return false;
1455
1456 Map<Symbol,Type> tMap = new HashMap<>();
1457 for (Type ti : interfaces(t)) {
1458 if (tMap.containsKey(ti)) {
1459 throw new AssertionError("Malformed intersection");
1460 }
1461 tMap.put(ti.tsym, ti);
1462 }
1463 for (Type si : interfaces(s)) {
1464 if (!tMap.containsKey(si.tsym))
1465 return false;
1466 Type ti = tMap.remove(si.tsym);
1467 if (!visit(ti, si))
1468 return false;
1469 }
1470 return tMap.isEmpty();
1471 }
1472 return t.tsym == s.tsym
1473 && t.isReferenceProjection() == s.isReferenceProjection()
1474 && visit(getEnclosingType(t), getEnclosingType(s))
1475 && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments());
1476 }
1477 // where
1478 private Type getEnclosingType(Type t) {
1479 Type et = t.getEnclosingType();
1480 if (et.isReferenceProjection()) {
1481 et = et.valueProjection();
1482 }
1483 return et;
1484 }
1485
1486 @Override
1487 public Boolean visitArrayType(ArrayType t, Type s) {
1488 if (t == s)
1489 return true;
1490
1491 if (s.isPartial())
1492 return visit(s, t);
1493
1494 return s.hasTag(ARRAY)
1495 && containsTypeEquivalent(t.elemtype, elemtype(s));
1496 }
1497
1498 @Override
1499 public Boolean visitMethodType(MethodType t, Type s) {
1500 // isSameType for methods does not take thrown
1501 // exceptions into account!
1502 return hasSameArgs(t, s) && visit(t.getReturnType(), s.getReturnType());
1503 }
1504
1624 // void debugContainsType(WildcardType t, Type s) {
1625 // System.err.println();
1626 // System.err.format(" does %s contain %s?%n", t, s);
1627 // System.err.format(" %s U(%s) <: U(%s) %s = %s%n",
1628 // wildUpperBound(s), s, t, wildUpperBound(t),
1629 // t.isSuperBound()
1630 // || isSubtypeNoCapture(wildUpperBound(s), wildUpperBound(t)));
1631 // System.err.format(" %s L(%s) <: L(%s) %s = %s%n",
1632 // wildLowerBound(t), t, s, wildLowerBound(s),
1633 // t.isExtendsBound()
1634 // || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s)));
1635 // System.err.println();
1636 // }
1637
1638 @Override
1639 public Boolean visitWildcardType(WildcardType t, Type s) {
1640 if (s.isPartial())
1641 return containedBy(s, t);
1642 else {
1643 // debugContainsType(t, s);
1644
1645 // ----------------------------------- Unspecified behavior ----------------
1646
1647 /* If a primitive class V implements an interface I, then does "? extends I" contain V?
1648 It seems widening must be applied here to answer yes to compile some common code
1649 patterns.
1650 */
1651
1652 // ---------------------------------------------------------------------------
1653 return isSameWildcard(t, s)
1654 || isCaptureOf(s, t)
1655 || ((t.isExtendsBound() || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s))) &&
1656 (t.isSuperBound() || isSubtypeNoCapture(wildUpperBound(s), wildUpperBound(t))));
1657 }
1658 }
1659
1660 @Override
1661 public Boolean visitUndetVar(UndetVar t, Type s) {
1662 if (!s.hasTag(WILDCARD)) {
1663 return isSameType(t, s);
1664 } else {
1665 return false;
1666 }
1667 }
1668
1669 @Override
1670 public Boolean visitErrorType(ErrorType t, Type s) {
1671 return true;
1672 }
1722 warnStack = warnStack.prepend(warn);
1723 checkUnsafeVarargsConversion(t, s, warn);
1724 result = isCastable.visit(t,s);
1725 } finally {
1726 warnStack = warnStack.tail;
1727 }
1728 } else {
1729 result = isCastable.visit(t,s);
1730 }
1731 if (result && t.hasTag(CLASS) && t.tsym.kind.matches(Kinds.KindSelector.TYP)
1732 && s.hasTag(CLASS) && s.tsym.kind.matches(Kinds.KindSelector.TYP)
1733 && (t.tsym.isSealed() || s.tsym.isSealed())) {
1734 return (t.isCompound() || s.isCompound()) ?
1735 true :
1736 !areDisjoint((ClassSymbol)t.tsym, (ClassSymbol)s.tsym);
1737 }
1738 return result;
1739 }
1740 // where
1741 private boolean areDisjoint(ClassSymbol ts, ClassSymbol ss) {
1742 if (isSubtype(erasure(ts.type.referenceProjectionOrSelf()), erasure(ss.type))) {
1743 return false;
1744 }
1745 // if both are classes or both are interfaces, shortcut
1746 if (ts.isInterface() == ss.isInterface() && isSubtype(erasure(ss.type), erasure(ts.type))) {
1747 return false;
1748 }
1749 if (ts.isInterface() && !ss.isInterface()) {
1750 /* so ts is interface but ss is a class
1751 * an interface is disjoint from a class if the class is disjoint form the interface
1752 */
1753 return areDisjoint(ss, ts);
1754 }
1755 // a final class that is not subtype of ss is disjoint
1756 if (!ts.isInterface() && ts.isFinal()) {
1757 return true;
1758 }
1759 // if at least one is sealed
1760 if (ts.isSealed() || ss.isSealed()) {
1761 // permitted subtypes have to be disjoint with the other symbol
1762 ClassSymbol sealedOne = ts.isSealed() ? ts : ss;
1777 case DOUBLE:
1778 return s.isNumeric();
1779 case BOOLEAN:
1780 return s.hasTag(BOOLEAN);
1781 case VOID:
1782 return false;
1783 case BOT:
1784 return isSubtype(t, s);
1785 default:
1786 throw new AssertionError();
1787 }
1788 }
1789
1790 @Override
1791 public Boolean visitWildcardType(WildcardType t, Type s) {
1792 return isCastable(wildUpperBound(t), s, warnStack.head);
1793 }
1794
1795 @Override
1796 public Boolean visitClassType(ClassType t, Type s) {
1797 if (s.hasTag(ERROR) || (s.hasTag(BOT) && (!allowPrimitiveClasses || !t.isPrimitiveClass())))
1798 return true;
1799
1800 if (s.hasTag(TYPEVAR)) {
1801 if (isCastable(t, s.getUpperBound(), noWarnings)) {
1802 warnStack.head.warn(LintCategory.UNCHECKED);
1803 return true;
1804 } else {
1805 return false;
1806 }
1807 }
1808
1809 if (t.isCompound() || s.isCompound()) {
1810 return !t.isCompound() ?
1811 visitCompoundType((ClassType)s, t, true) :
1812 visitCompoundType(t, s, false);
1813 }
1814
1815 if (s.hasTag(CLASS) || s.hasTag(ARRAY)) {
1816 if (allowPrimitiveClasses) {
1817 if (t.isPrimitiveClass()) {
1818 // (s) Value ? == (s) Value.ref
1819 t = t.referenceProjection();
1820 }
1821 if (s.isPrimitiveClass()) {
1822 // (Value) t ? == (Value.ref) t
1823 s = s.referenceProjection();
1824 }
1825 }
1826 boolean upcast;
1827 if ((upcast = isSubtype(erasure(t), erasure(s)))
1828 || isSubtype(erasure(s), erasure(t))) {
1829 if (!upcast && s.hasTag(ARRAY)) {
1830 if (!isReifiable(s))
1831 warnStack.head.warn(LintCategory.UNCHECKED);
1832 return true;
1833 } else if (s.isRaw()) {
1834 return true;
1835 } else if (t.isRaw()) {
1836 if (!isUnbounded(s))
1837 warnStack.head.warn(LintCategory.UNCHECKED);
1838 return true;
1839 }
1840 // Assume |a| <: |b|
1841 final Type a = upcast ? t : s;
1842 final Type b = upcast ? s : t;
1843 final boolean HIGH = true;
1844 final boolean LOW = false;
1845 final boolean DONT_REWRITE_TYPEVARS = false;
2199 * @return the ArrayType for the given component
2200 */
2201 public ArrayType makeArrayType(Type t) {
2202 if (t.hasTag(VOID) || t.hasTag(PACKAGE)) {
2203 Assert.error("Type t must not be a VOID or PACKAGE type, " + t.toString());
2204 }
2205 return new ArrayType(t, syms.arrayClass);
2206 }
2207 // </editor-fold>
2208
2209 // <editor-fold defaultstate="collapsed" desc="asSuper">
2210 /**
2211 * Return the (most specific) base type of t that starts with the
2212 * given symbol. If none exists, return null.
2213 *
2214 * Caveat Emptor: Since javac represents the class of all arrays with a singleton
2215 * symbol Symtab.arrayClass, which by being a singleton cannot hold any discriminant,
2216 * this method could yield surprising answers when invoked on arrays. For example when
2217 * invoked with t being byte [] and sym being t.sym itself, asSuper would answer null.
2218 *
2219 * Further caveats in Valhalla: There are two "hazards" we need to watch out for when using
2220 * this method.
2221 *
2222 * 1. Since Foo.ref and Foo.val share the same symbol, that of Foo.class, a call to
2223 * asSuper(Foo.ref.type, Foo.val.type.tsym) would return non-null. This MAY NOT BE correct
2224 * depending on the call site. Foo.val is NOT a super type of Foo.ref either in the language
2225 * model or in the VM's world view. An example of such an hazardous call used to exist in
2226 * Gen.visitTypeCast. When we emit code for (Foo) Foo.ref.instance a check for whether we
2227 * really need the cast cannot/shouldn't be gated on
2228 *
2229 * asSuper(tree.expr.type, tree.clazz.type.tsym) == null)
2230 *
2231 * but use !types.isSubtype(tree.expr.type, tree.clazz.type) which operates in terms of
2232 * types. When we operate in terms of symbols, there is a loss of type information leading
2233 * to a hazard. Whether a call to asSuper should be transformed into a isSubtype call is
2234 * tricky. isSubtype returns just a boolean while asSuper returns richer information which
2235 * may be required at the call site. Also where the concerned symbol corresponds to a
2236 * generic class, an asSuper call cannot be conveniently rewritten as an isSubtype call
2237 * (see that asSuper(ArrayList<String>.type, List<T>.tsym) != null while
2238 * isSubType(ArrayList<String>.type, List<T>.type) is false;) So care needs to be exercised.
2239 *
2240 * 2. Given a primitive class Foo, a call to asSuper(Foo.type, SuperclassOfFoo.tsym) and/or
2241 * a call to asSuper(Foo.type, SuperinterfaceOfFoo.tsym) would answer null. In many places
2242 * that is NOT what we want. An example of such a hazardous call used to occur in
2243 * Attr.visitForeachLoop when checking to make sure the for loop's control variable of a type
2244 * that implements Iterable: viz: types.asSuper(exprType, syms.iterableType.tsym);
2245 * These hazardous calls should be rewritten as
2246 * types.asSuper(exprType.referenceProjectionOrSelf(), syms.iterableType.tsym); instead.
2247 *
2248 * @param t a type
2249 * @param sym a symbol
2250 */
2251 public Type asSuper(Type t, Symbol sym) {
2252 /* Some examples:
2253 *
2254 * (Enum<E>, Comparable) => Comparable<E>
2255 * (c.s.s.d.AttributeTree.ValueKind, Enum) => Enum<c.s.s.d.AttributeTree.ValueKind>
2256 * (c.s.s.t.ExpressionTree, c.s.s.t.Tree) => c.s.s.t.Tree
2257 * (j.u.List<capture#160 of ? extends c.s.s.d.DocTree>, Iterable) =>
2258 * Iterable<capture#160 of ? extends c.s.s.d.DocTree>
2259 */
2260
2261 if (allowPrimitiveClasses && t.isPrimitiveClass()) {
2262 // No man may be an island, but the bell tolls for a value.
2263 return t.tsym == sym ? t : null;
2264 }
2265
2266 if (sym.type == syms.objectType) { //optimization
2267 return syms.objectType;
2268 }
2269 return asSuper.visit(t, sym);
2270 }
2271 // where
2272 private SimpleVisitor<Type,Symbol> asSuper = new SimpleVisitor<Type,Symbol>() {
2273
2274 private Set<Symbol> seenTypes = new HashSet<>();
2275
2276 public Type visitType(Type t, Symbol sym) {
2277 return null;
2278 }
2279
2280 @Override
2281 public Type visitClassType(ClassType t, Symbol sym) {
2282 if (t.tsym == sym)
2283 return t;
2284
2285 Symbol c = t.tsym;
2376 case ARRAY:
2377 return isSubtype(t, sym.type) ? sym.type : null;
2378 case TYPEVAR:
2379 return asSuper(t, sym);
2380 case ERROR:
2381 return t;
2382 default:
2383 return null;
2384 }
2385 }
2386 // </editor-fold>
2387
2388 // <editor-fold defaultstate="collapsed" desc="memberType">
2389 /**
2390 * The type of given symbol, seen as a member of t.
2391 *
2392 * @param t a type
2393 * @param sym a symbol
2394 */
2395 public Type memberType(Type t, Symbol sym) {
2396
2397 if ((sym.flags() & STATIC) != 0)
2398 return sym.type;
2399
2400 /* If any primitive class types are involved, switch over to the reference universe,
2401 where the hierarchy is navigable. V and V.ref have identical membership
2402 with no bridging needs.
2403 */
2404 if (allowPrimitiveClasses && t.isPrimitiveClass())
2405 t = t.referenceProjection();
2406
2407 return memberType.visit(t, sym);
2408 }
2409 // where
2410 private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
2411
2412 public Type visitType(Type t, Symbol sym) {
2413 return sym.type;
2414 }
2415
2416 @Override
2417 public Type visitWildcardType(WildcardType t, Symbol sym) {
2418 return memberType(wildUpperBound(t), sym);
2419 }
2420
2421 @Override
2422 public Type visitClassType(ClassType t, Symbol sym) {
2423 Symbol owner = sym.owner;
2424 long flags = sym.flags();
2425 if (((flags & STATIC) == 0) && owner.type.isParameterized()) {
2426 Type base = asOuterSuper(t, owner);
2427 //if t is an intersection type T = CT & I1 & I2 ... & In
2540 }
2541 }
2542
2543 public Type visitType(Type t, Boolean recurse) {
2544 if (t.isPrimitive())
2545 return t; /*fast special case*/
2546 else {
2547 //other cases already handled
2548 return combineMetadata(t, t);
2549 }
2550 }
2551
2552 @Override
2553 public Type visitWildcardType(WildcardType t, Boolean recurse) {
2554 Type erased = erasure(wildUpperBound(t), recurse);
2555 return combineMetadata(erased, t);
2556 }
2557
2558 @Override
2559 public Type visitClassType(ClassType t, Boolean recurse) {
2560 // erasure(projection(primitive)) = projection(erasure(primitive))
2561 Type erased = eraseClassType(t, recurse);
2562 if (erased.hasTag(CLASS) && t.flavor != erased.getFlavor()) {
2563 erased = new ClassType(erased.getEnclosingType(),
2564 List.nil(), erased.tsym,
2565 erased.getMetadata(), t.flavor);
2566 }
2567 return erased;
2568 }
2569 // where
2570 private Type eraseClassType(ClassType t, Boolean recurse) {
2571 Type erased = t.tsym.erasure(Types.this);
2572 if (recurse) {
2573 erased = new ErasedClassType(erased.getEnclosingType(), erased.tsym,
2574 t.getMetadata().without(Kind.ANNOTATIONS));
2575 return erased;
2576 } else {
2577 return combineMetadata(erased, t);
2578 }
2579 }
2580
2581 @Override
2582 public Type visitTypeVar(TypeVar t, Boolean recurse) {
2583 Type erased = erasure(t.getUpperBound(), recurse);
2584 return combineMetadata(erased, t);
2585 }
2586 };
2587
2588 public List<Type> erasure(List<Type> ts) {
2589 return erasure.visit(ts, false);
2590 }
2591
2592 public Type erasureRecursive(Type t) {
2593 return erasure(t, true);
2594 }
2595
2596 public List<Type> erasureRecursive(List<Type> ts) {
2597 return erasure.visit(ts, true);
2598 }
2599 // </editor-fold>
2879 /**
2880 * If the given type is a (possibly selected) type variable,
2881 * return the bounding class of this type, otherwise return the
2882 * type itself.
2883 */
2884 public Type classBound(Type t) {
2885 return classBound.visit(t);
2886 }
2887 // where
2888 private UnaryVisitor<Type> classBound = new UnaryVisitor<Type>() {
2889
2890 public Type visitType(Type t, Void ignored) {
2891 return t;
2892 }
2893
2894 @Override
2895 public Type visitClassType(ClassType t, Void ignored) {
2896 Type outer1 = classBound(t.getEnclosingType());
2897 if (outer1 != t.getEnclosingType())
2898 return new ClassType(outer1, t.getTypeArguments(), t.tsym,
2899 t.getMetadata(), t.getFlavor());
2900 else
2901 return t;
2902 }
2903
2904 @Override
2905 public Type visitTypeVar(TypeVar t, Void ignored) {
2906 return classBound(supertype(t));
2907 }
2908
2909 @Override
2910 public Type visitErrorType(ErrorType t, Void ignored) {
2911 return t;
2912 }
2913 };
2914 // </editor-fold>
2915
2916 // <editor-fold defaultstate="collapsed" desc="subsignature / override equivalence">
2917 /**
2918 * Returns true iff the first signature is a <em>subsignature</em>
2919 * of the other. This is <b>not</b> an equivalence
4050 m = new WildcardType(lub(wildUpperBound(act1.head),
4051 wildUpperBound(act2.head)),
4052 BoundKind.EXTENDS,
4053 syms.boundClass);
4054 mergeCache.remove(pair);
4055 } else {
4056 m = new WildcardType(syms.objectType,
4057 BoundKind.UNBOUND,
4058 syms.boundClass);
4059 }
4060 merged.append(m.withTypeVar(typarams.head));
4061 }
4062 act1 = act1.tail;
4063 act2 = act2.tail;
4064 typarams = typarams.tail;
4065 }
4066 Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
4067 // There is no spec detailing how type annotations are to
4068 // be inherited. So set it to noAnnotations for now
4069 return new ClassType(class1.getEnclosingType(), merged.toList(),
4070 class1.tsym, TypeMetadata.EMPTY, class1.getFlavor());
4071 }
4072
4073 /**
4074 * Return the minimum type of a closure, a compound type if no
4075 * unique minimum exists.
4076 */
4077 private Type compoundMin(List<Type> cl) {
4078 if (cl.isEmpty()) return syms.objectType;
4079 List<Type> compound = closureMin(cl);
4080 if (compound.isEmpty())
4081 return null;
4082 else if (compound.tail.isEmpty())
4083 return compound.head;
4084 else
4085 return makeIntersectionType(compound);
4086 }
4087
4088 /**
4089 * Return the minimum types of a closure, suitable for computing
4090 * compoundMin or glb.
4610 Si.lower = Ti.getSuperBound();
4611 break;
4612 }
4613 Type tmpBound = Si.getUpperBound().hasTag(UNDETVAR) ? ((UndetVar)Si.getUpperBound()).qtype : Si.getUpperBound();
4614 Type tmpLower = Si.lower.hasTag(UNDETVAR) ? ((UndetVar)Si.lower).qtype : Si.lower;
4615 if (!Si.getUpperBound().hasTag(ERROR) &&
4616 !Si.lower.hasTag(ERROR) &&
4617 isSameType(tmpBound, tmpLower)) {
4618 currentS.head = Si.getUpperBound();
4619 }
4620 }
4621 currentA = currentA.tail;
4622 currentT = currentT.tail;
4623 currentS = currentS.tail;
4624 }
4625 if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty())
4626 return erasure(t); // some "rare" type involved
4627
4628 if (captured)
4629 return new ClassType(cls.getEnclosingType(), S, cls.tsym,
4630 cls.getMetadata(), cls.getFlavor());
4631 else
4632 return t;
4633 }
4634 // where
4635 public List<Type> freshTypeVariables(List<Type> types) {
4636 ListBuffer<Type> result = new ListBuffer<>();
4637 for (Type t : types) {
4638 if (t.hasTag(WILDCARD)) {
4639 Type bound = ((WildcardType)t).getExtendsBound();
4640 if (bound == null)
4641 bound = syms.objectType;
4642 result.append(new CapturedType(capturedName,
4643 syms.noSymbol,
4644 bound,
4645 syms.botType,
4646 (WildcardType)t));
4647 } else {
4648 result.append(t);
4649 }
4650 }
5021 private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
5022 if (bound.hasTag(BOT)) {
5023 return new WildcardType(syms.objectType,
5024 BoundKind.UNBOUND,
5025 syms.boundClass,
5026 formal);
5027 } else {
5028 return new WildcardType(bound,
5029 BoundKind.SUPER,
5030 syms.boundClass,
5031 formal);
5032 }
5033 }
5034
5035 /**
5036 * A wrapper for a type that allows use in sets.
5037 */
5038 public static class UniqueType {
5039 public final Type type;
5040 final Types types;
5041 private boolean encodeTypeSig;
5042
5043 public UniqueType(Type type, Types types, boolean encodeTypeSig) {
5044 this.type = type;
5045 this.types = types;
5046 this.encodeTypeSig = encodeTypeSig;
5047 }
5048
5049 public UniqueType(Type type, Types types) {
5050 this(type, types, true);
5051 }
5052
5053 public int hashCode() {
5054 return types.hashCode(type);
5055 }
5056
5057 public boolean equals(Object obj) {
5058 return (obj instanceof UniqueType uniqueType) &&
5059 types.isSameType(type, uniqueType.type);
5060 }
5061
5062 public boolean encodeTypeSig() {
5063 return encodeTypeSig;
5064 }
5065
5066 public String toString() {
5067 return type.toString();
5068 }
5069
5070 }
5071 // </editor-fold>
5072
5073 // <editor-fold defaultstate="collapsed" desc="Visitors">
5074 /**
5075 * A default visitor for types. All visitor methods except
5076 * visitType are implemented by delegating to visitType. Concrete
5077 * subclasses must provide an implementation of visitType and can
5078 * override other methods as needed.
5079 *
5080 * @param <R> the return type of the operation implemented by this
5081 * visitor; use Void if no return type is needed.
5082 * @param <S> the type of the second argument (the first being the
5083 * type itself) of the operation implemented by this visitor; use
5084 * Void if a second argument is not needed.
5085 */
5284 break;
5285 case LONG:
5286 append('J');
5287 break;
5288 case FLOAT:
5289 append('F');
5290 break;
5291 case DOUBLE:
5292 append('D');
5293 break;
5294 case BOOLEAN:
5295 append('Z');
5296 break;
5297 case VOID:
5298 append('V');
5299 break;
5300 case CLASS:
5301 if (type.isCompound()) {
5302 reportIllegalSignature(type);
5303 }
5304 if (types.allowPrimitiveClasses && type.isPrimitiveClass())
5305 append('Q');
5306 else
5307 append('L');
5308 assembleClassSig(type);
5309 append(';');
5310 break;
5311 case ARRAY:
5312 ArrayType at = (ArrayType) type;
5313 append('[');
5314 assembleSig(at.elemtype);
5315 break;
5316 case METHOD:
5317 MethodType mt = (MethodType) type;
5318 append('(');
5319 assembleSig(mt.argtypes);
5320 append(')');
5321 assembleSig(mt.restype);
5322 if (hasTypeVar(mt.thrown)) {
5323 for (List<Type> l = mt.thrown; l.nonEmpty(); l = l.tail) {
5324 append('^');
5325 assembleSig(l.head);
5326 }
5327 }
|