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.Annotations;
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 @SuppressWarnings("this-escape")
112 protected Types(Context context) {
113 context.put(typesKey, this);
114 syms = Symtab.instance(context);
115 names = Names.instance(context);
116 Source source = Source.instance(context);
117 chk = Check.instance(context);
118 enter = Enter.instance(context);
119 capturedName = names.fromString("<captured wildcard>");
120 messages = JavacMessages.instance(context);
121 diags = JCDiagnostic.Factory.instance(context);
122 noWarnings = new Warner(null);
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
142 /**
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)
1403 return visit(t, wildUpperBound(s)) && visit(t, wildLowerBound(s));
1404
1405 if (t.isCompound() && s.isCompound()) {
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 tMap.put(ti.tsym, ti);
1412 }
1413 for (Type si : interfaces(s)) {
1414 if (!tMap.containsKey(si.tsym))
1415 return false;
1416 Type ti = tMap.remove(si.tsym);
1417 if (!visit(ti, si))
1418 return false;
1419 }
1420 return tMap.isEmpty();
1421 }
1422 return t.tsym == s.tsym
1423 && visit(t.getEnclosingType(), s.getEnclosingType())
1424 && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments());
1425 }
1426
1427 @Override
1428 public Boolean visitArrayType(ArrayType t, Type s) {
1429 if (t == s)
1430 return true;
1431
1432 if (s.isPartial())
1433 return visit(s, t);
1434
1435 return s.hasTag(ARRAY)
1436 && containsTypeEquivalent(t.elemtype, elemtype(s));
1437 }
1438
1439 @Override
1440 public Boolean visitMethodType(MethodType t, Type s) {
1441 // isSameType for methods does not take thrown
1442 // exceptions into account!
1443 return hasSameArgs(t, s) && visit(t.getReturnType(), s.getReturnType());
1444 }
1445
1565 // void debugContainsType(WildcardType t, Type s) {
1566 // System.err.println();
1567 // System.err.format(" does %s contain %s?%n", t, s);
1568 // System.err.format(" %s U(%s) <: U(%s) %s = %s%n",
1569 // wildUpperBound(s), s, t, wildUpperBound(t),
1570 // t.isSuperBound()
1571 // || isSubtypeNoCapture(wildUpperBound(s), wildUpperBound(t)));
1572 // System.err.format(" %s L(%s) <: L(%s) %s = %s%n",
1573 // wildLowerBound(t), t, s, wildLowerBound(s),
1574 // t.isExtendsBound()
1575 // || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s)));
1576 // System.err.println();
1577 // }
1578
1579 @Override
1580 public Boolean visitWildcardType(WildcardType t, Type s) {
1581 if (s.isPartial())
1582 return containedBy(s, t);
1583 else {
1584 // debugContainsType(t, s);
1585 return isSameWildcard(t, s)
1586 || isCaptureOf(s, t)
1587 || ((t.isExtendsBound() || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s))) &&
1588 (t.isSuperBound() || isSubtypeNoCapture(wildUpperBound(s), wildUpperBound(t))));
1589 }
1590 }
1591
1592 @Override
1593 public Boolean visitUndetVar(UndetVar t, Type s) {
1594 if (!s.hasTag(WILDCARD)) {
1595 return isSameType(t, s);
1596 } else {
1597 return false;
1598 }
1599 }
1600
1601 @Override
1602 public Boolean visitErrorType(ErrorType t, Type s) {
1603 return true;
1604 }
1654 warnStack = warnStack.prepend(warn);
1655 checkUnsafeVarargsConversion(t, s, warn);
1656 result = isCastable.visit(t,s);
1657 } finally {
1658 warnStack = warnStack.tail;
1659 }
1660 } else {
1661 result = isCastable.visit(t,s);
1662 }
1663 if (result && t.hasTag(CLASS) && t.tsym.kind.matches(Kinds.KindSelector.TYP)
1664 && s.hasTag(CLASS) && s.tsym.kind.matches(Kinds.KindSelector.TYP)
1665 && (t.tsym.isSealed() || s.tsym.isSealed())) {
1666 return (t.isCompound() || s.isCompound()) ?
1667 true :
1668 !areDisjoint((ClassSymbol)t.tsym, (ClassSymbol)s.tsym);
1669 }
1670 return result;
1671 }
1672 // where
1673 private boolean areDisjoint(ClassSymbol ts, ClassSymbol ss) {
1674 if (isSubtype(erasure(ts.type), erasure(ss.type))) {
1675 return false;
1676 }
1677 // if both are classes or both are interfaces, shortcut
1678 if (ts.isInterface() == ss.isInterface() && isSubtype(erasure(ss.type), erasure(ts.type))) {
1679 return false;
1680 }
1681 if (ts.isInterface() && !ss.isInterface()) {
1682 /* so ts is interface but ss is a class
1683 * an interface is disjoint from a class if the class is disjoint form the interface
1684 */
1685 return areDisjoint(ss, ts);
1686 }
1687 // a final class that is not subtype of ss is disjoint
1688 if (!ts.isInterface() && ts.isFinal()) {
1689 return true;
1690 }
1691 // if at least one is sealed
1692 if (ts.isSealed() || ss.isSealed()) {
1693 // permitted subtypes have to be disjoint with the other symbol
1694 ClassSymbol sealedOne = ts.isSealed() ? ts : ss;
1709 case DOUBLE:
1710 return s.isNumeric();
1711 case BOOLEAN:
1712 return s.hasTag(BOOLEAN);
1713 case VOID:
1714 return false;
1715 case BOT:
1716 return isSubtype(t, s);
1717 default:
1718 throw new AssertionError();
1719 }
1720 }
1721
1722 @Override
1723 public Boolean visitWildcardType(WildcardType t, Type s) {
1724 return isCastable(wildUpperBound(t), s, warnStack.head);
1725 }
1726
1727 @Override
1728 public Boolean visitClassType(ClassType t, Type s) {
1729 if (s.hasTag(ERROR) || s.hasTag(BOT))
1730 return true;
1731
1732 if (s.hasTag(TYPEVAR)) {
1733 if (isCastable(t, s.getUpperBound(), noWarnings)) {
1734 warnStack.head.warn(LintCategory.UNCHECKED);
1735 return true;
1736 } else {
1737 return false;
1738 }
1739 }
1740
1741 if (t.isCompound() || s.isCompound()) {
1742 return !t.isCompound() ?
1743 visitCompoundType((ClassType)s, t, true) :
1744 visitCompoundType(t, s, false);
1745 }
1746
1747 if (s.hasTag(CLASS) || s.hasTag(ARRAY)) {
1748 boolean upcast;
1749 if ((upcast = isSubtype(erasure(t), erasure(s)))
1750 || isSubtype(erasure(s), erasure(t))) {
1751 if (!upcast && s.hasTag(ARRAY)) {
1752 if (!isReifiable(s))
1753 warnStack.head.warn(LintCategory.UNCHECKED);
1754 return true;
1755 } else if (s.isRaw()) {
1756 return true;
1757 } else if (t.isRaw()) {
1758 if (!isUnbounded(s))
1759 warnStack.head.warn(LintCategory.UNCHECKED);
1760 return true;
1761 }
1762 // Assume |a| <: |b|
1763 final Type a = upcast ? t : s;
1764 final Type b = upcast ? s : t;
1765 final boolean HIGH = true;
1766 final boolean LOW = false;
1767 final boolean DONT_REWRITE_TYPEVARS = false;
2121 * @return the ArrayType for the given component
2122 */
2123 public ArrayType makeArrayType(Type t) {
2124 if (t.hasTag(VOID) || t.hasTag(PACKAGE)) {
2125 Assert.error("Type t must not be a VOID or PACKAGE type, " + t.toString());
2126 }
2127 return new ArrayType(t, syms.arrayClass);
2128 }
2129 // </editor-fold>
2130
2131 // <editor-fold defaultstate="collapsed" desc="asSuper">
2132 /**
2133 * Return the (most specific) base type of t that starts with the
2134 * given symbol. If none exists, return null.
2135 *
2136 * Caveat Emptor: Since javac represents the class of all arrays with a singleton
2137 * symbol Symtab.arrayClass, which by being a singleton cannot hold any discriminant,
2138 * this method could yield surprising answers when invoked on arrays. For example when
2139 * invoked with t being byte [] and sym being t.sym itself, asSuper would answer null.
2140 *
2141 * @param t a type
2142 * @param sym a symbol
2143 */
2144 public Type asSuper(Type t, Symbol sym) {
2145 /* Some examples:
2146 *
2147 * (Enum<E>, Comparable) => Comparable<E>
2148 * (c.s.s.d.AttributeTree.ValueKind, Enum) => Enum<c.s.s.d.AttributeTree.ValueKind>
2149 * (c.s.s.t.ExpressionTree, c.s.s.t.Tree) => c.s.s.t.Tree
2150 * (j.u.List<capture#160 of ? extends c.s.s.d.DocTree>, Iterable) =>
2151 * Iterable<capture#160 of ? extends c.s.s.d.DocTree>
2152 */
2153 if (sym.type == syms.objectType) { //optimization
2154 return syms.objectType;
2155 }
2156 return asSuper.visit(t, sym);
2157 }
2158 // where
2159 private SimpleVisitor<Type,Symbol> asSuper = new SimpleVisitor<Type,Symbol>() {
2160
2161 private Set<Symbol> seenTypes = new HashSet<>();
2162
2163 public Type visitType(Type t, Symbol sym) {
2164 return null;
2165 }
2166
2167 @Override
2168 public Type visitClassType(ClassType t, Symbol sym) {
2169 if (t.tsym == sym)
2170 return t;
2171
2172 Symbol c = t.tsym;
2263 case ARRAY:
2264 return isSubtype(t, sym.type) ? sym.type : null;
2265 case TYPEVAR:
2266 return asSuper(t, sym);
2267 case ERROR:
2268 return t;
2269 default:
2270 return null;
2271 }
2272 }
2273 // </editor-fold>
2274
2275 // <editor-fold defaultstate="collapsed" desc="memberType">
2276 /**
2277 * The type of given symbol, seen as a member of t.
2278 *
2279 * @param t a type
2280 * @param sym a symbol
2281 */
2282 public Type memberType(Type t, Symbol sym) {
2283 return (sym.flags() & STATIC) != 0
2284 ? sym.type
2285 : memberType.visit(t, sym);
2286 }
2287 // where
2288 private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
2289
2290 public Type visitType(Type t, Symbol sym) {
2291 return sym.type;
2292 }
2293
2294 @Override
2295 public Type visitWildcardType(WildcardType t, Symbol sym) {
2296 return memberType(wildUpperBound(t), sym);
2297 }
2298
2299 @Override
2300 public Type visitClassType(ClassType t, Symbol sym) {
2301 Symbol owner = sym.owner;
2302 long flags = sym.flags();
2303 if (((flags & STATIC) == 0) && owner.type.isParameterized()) {
2304 Type base = asOuterSuper(t, owner);
2305 //if t is an intersection type T = CT & I1 & I2 ... & In
2418 }
2419 }
2420
2421 public Type visitType(Type t, Boolean recurse) {
2422 if (t.isPrimitive())
2423 return t; /*fast special case*/
2424 else {
2425 //other cases already handled
2426 return combineMetadata(t, t);
2427 }
2428 }
2429
2430 @Override
2431 public Type visitWildcardType(WildcardType t, Boolean recurse) {
2432 Type erased = erasure(wildUpperBound(t), recurse);
2433 return combineMetadata(erased, t);
2434 }
2435
2436 @Override
2437 public Type visitClassType(ClassType t, Boolean recurse) {
2438 Type erased = t.tsym.erasure(Types.this);
2439 if (recurse) {
2440 erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym,
2441 t.dropMetadata(Annotations.class).getMetadata());
2442 return erased;
2443 } else {
2444 return combineMetadata(erased, t);
2445 }
2446 }
2447
2448 @Override
2449 public Type visitTypeVar(TypeVar t, Boolean recurse) {
2450 Type erased = erasure(t.getUpperBound(), recurse);
2451 return combineMetadata(erased, t);
2452 }
2453 };
2454
2455 public List<Type> erasure(List<Type> ts) {
2456 return erasure.visit(ts, false);
2457 }
2458
2459 public Type erasureRecursive(Type t) {
2460 return erasure(t, true);
2461 }
2462
2463 public List<Type> erasureRecursive(List<Type> ts) {
2464 return erasure.visit(ts, true);
2465 }
2466 // </editor-fold>
2746 /**
2747 * If the given type is a (possibly selected) type variable,
2748 * return the bounding class of this type, otherwise return the
2749 * type itself.
2750 */
2751 public Type classBound(Type t) {
2752 return classBound.visit(t);
2753 }
2754 // where
2755 private UnaryVisitor<Type> classBound = new UnaryVisitor<Type>() {
2756
2757 public Type visitType(Type t, Void ignored) {
2758 return t;
2759 }
2760
2761 @Override
2762 public Type visitClassType(ClassType t, Void ignored) {
2763 Type outer1 = classBound(t.getEnclosingType());
2764 if (outer1 != t.getEnclosingType())
2765 return new ClassType(outer1, t.getTypeArguments(), t.tsym,
2766 t.getMetadata());
2767 else
2768 return t;
2769 }
2770
2771 @Override
2772 public Type visitTypeVar(TypeVar t, Void ignored) {
2773 return classBound(supertype(t));
2774 }
2775
2776 @Override
2777 public Type visitErrorType(ErrorType t, Void ignored) {
2778 return t;
2779 }
2780 };
2781 // </editor-fold>
2782
2783 // <editor-fold defaultstate="collapsed" desc="subsignature / override equivalence">
2784 /**
2785 * Returns true iff the first signature is a <em>subsignature</em>
2786 * of the other. This is <b>not</b> an equivalence
3867 m = new WildcardType(lub(wildUpperBound(act1.head),
3868 wildUpperBound(act2.head)),
3869 BoundKind.EXTENDS,
3870 syms.boundClass);
3871 mergeCache.remove(pair);
3872 } else {
3873 m = new WildcardType(syms.objectType,
3874 BoundKind.UNBOUND,
3875 syms.boundClass);
3876 }
3877 merged.append(m.withTypeVar(typarams.head));
3878 }
3879 act1 = act1.tail;
3880 act2 = act2.tail;
3881 typarams = typarams.tail;
3882 }
3883 Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
3884 // There is no spec detailing how type annotations are to
3885 // be inherited. So set it to noAnnotations for now
3886 return new ClassType(class1.getEnclosingType(), merged.toList(),
3887 class1.tsym);
3888 }
3889
3890 /**
3891 * Return the minimum type of a closure, a compound type if no
3892 * unique minimum exists.
3893 */
3894 private Type compoundMin(List<Type> cl) {
3895 if (cl.isEmpty()) return syms.objectType;
3896 List<Type> compound = closureMin(cl);
3897 if (compound.isEmpty())
3898 return null;
3899 else if (compound.tail.isEmpty())
3900 return compound.head;
3901 else
3902 return makeIntersectionType(compound);
3903 }
3904
3905 /**
3906 * Return the minimum types of a closure, suitable for computing
3907 * compoundMin or glb.
4427 Si.lower = Ti.getSuperBound();
4428 break;
4429 }
4430 Type tmpBound = Si.getUpperBound().hasTag(UNDETVAR) ? ((UndetVar)Si.getUpperBound()).qtype : Si.getUpperBound();
4431 Type tmpLower = Si.lower.hasTag(UNDETVAR) ? ((UndetVar)Si.lower).qtype : Si.lower;
4432 if (!Si.getUpperBound().hasTag(ERROR) &&
4433 !Si.lower.hasTag(ERROR) &&
4434 isSameType(tmpBound, tmpLower)) {
4435 currentS.head = Si.getUpperBound();
4436 }
4437 }
4438 currentA = currentA.tail;
4439 currentT = currentT.tail;
4440 currentS = currentS.tail;
4441 }
4442 if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty())
4443 return erasure(t); // some "rare" type involved
4444
4445 if (captured)
4446 return new ClassType(cls.getEnclosingType(), S, cls.tsym,
4447 cls.getMetadata());
4448 else
4449 return t;
4450 }
4451 // where
4452 public List<Type> freshTypeVariables(List<Type> types) {
4453 ListBuffer<Type> result = new ListBuffer<>();
4454 for (Type t : types) {
4455 if (t.hasTag(WILDCARD)) {
4456 Type bound = ((WildcardType)t).getExtendsBound();
4457 if (bound == null)
4458 bound = syms.objectType;
4459 result.append(new CapturedType(capturedName,
4460 syms.noSymbol,
4461 bound,
4462 syms.botType,
4463 (WildcardType)t));
4464 } else {
4465 result.append(t);
4466 }
4467 }
4838 private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
4839 if (bound.hasTag(BOT)) {
4840 return new WildcardType(syms.objectType,
4841 BoundKind.UNBOUND,
4842 syms.boundClass,
4843 formal);
4844 } else {
4845 return new WildcardType(bound,
4846 BoundKind.SUPER,
4847 syms.boundClass,
4848 formal);
4849 }
4850 }
4851
4852 /**
4853 * A wrapper for a type that allows use in sets.
4854 */
4855 public static class UniqueType {
4856 public final Type type;
4857 final Types types;
4858
4859 public UniqueType(Type type, Types types) {
4860 this.type = type;
4861 this.types = types;
4862 }
4863
4864 public int hashCode() {
4865 return types.hashCode(type);
4866 }
4867
4868 public boolean equals(Object obj) {
4869 return (obj instanceof UniqueType uniqueType) &&
4870 types.isSameType(type, uniqueType.type);
4871 }
4872
4873 public String toString() {
4874 return type.toString();
4875 }
4876
4877 }
4878 // </editor-fold>
4879
4880 // <editor-fold defaultstate="collapsed" desc="Visitors">
4881 /**
4882 * A default visitor for types. All visitor methods except
4883 * visitType are implemented by delegating to visitType. Concrete
4884 * subclasses must provide an implementation of visitType and can
4885 * override other methods as needed.
4886 *
4887 * @param <R> the return type of the operation implemented by this
4888 * visitor; use Void if no return type is needed.
4889 * @param <S> the type of the second argument (the first being the
4890 * type itself) of the operation implemented by this visitor; use
4891 * Void if a second argument is not needed.
4892 */
5091 break;
5092 case LONG:
5093 append('J');
5094 break;
5095 case FLOAT:
5096 append('F');
5097 break;
5098 case DOUBLE:
5099 append('D');
5100 break;
5101 case BOOLEAN:
5102 append('Z');
5103 break;
5104 case VOID:
5105 append('V');
5106 break;
5107 case CLASS:
5108 if (type.isCompound()) {
5109 reportIllegalSignature(type);
5110 }
5111 append('L');
5112 assembleClassSig(type);
5113 append(';');
5114 break;
5115 case ARRAY:
5116 ArrayType at = (ArrayType) type;
5117 append('[');
5118 assembleSig(at.elemtype);
5119 break;
5120 case METHOD:
5121 MethodType mt = (MethodType) type;
5122 append('(');
5123 assembleSig(mt.argtypes);
5124 append(')');
5125 assembleSig(mt.restype);
5126 if (hasTypeVar(mt.thrown)) {
5127 for (List<Type> l = mt.thrown; l.nonEmpty(); l = l.tail) {
5128 append('^');
5129 assembleSig(l.head);
5130 }
5131 }
|
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.Annotations;
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 @SuppressWarnings("this-escape")
112 protected Types(Context context) {
113 context.put(typesKey, this);
114 syms = Symtab.instance(context);
115 names = Names.instance(context);
116 Source source = Source.instance(context);
117 chk = Check.instance(context);
118 enter = Enter.instance(context);
119 capturedName = names.fromString("<captured wildcard>");
120 messages = JavacMessages.instance(context);
121 diags = JCDiagnostic.Factory.instance(context);
122 noWarnings = new Warner(null);
123 Options options = Options.instance(context);
124 allowPrimitiveClasses = Feature.PRIMITIVE_CLASSES.allowedInSource(source) && options.isSet("enablePrimitiveClasses");
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
144 /**
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)
1450 return visit(t, wildUpperBound(s)) && visit(t, wildLowerBound(s));
1451
1452 if (t.isCompound() && s.isCompound()) {
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 tMap.put(ti.tsym, ti);
1459 }
1460 for (Type si : interfaces(s)) {
1461 if (!tMap.containsKey(si.tsym))
1462 return false;
1463 Type ti = tMap.remove(si.tsym);
1464 if (!visit(ti, si))
1465 return false;
1466 }
1467 return tMap.isEmpty();
1468 }
1469 return t.tsym == s.tsym
1470 && t.isReferenceProjection() == s.isReferenceProjection()
1471 && visit(getEnclosingType(t), getEnclosingType(s))
1472 && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments());
1473 }
1474 // where
1475 private Type getEnclosingType(Type t) {
1476 Type et = t.getEnclosingType();
1477 if (et.isReferenceProjection()) {
1478 et = et.valueProjection();
1479 }
1480 return et;
1481 }
1482
1483 @Override
1484 public Boolean visitArrayType(ArrayType t, Type s) {
1485 if (t == s)
1486 return true;
1487
1488 if (s.isPartial())
1489 return visit(s, t);
1490
1491 return s.hasTag(ARRAY)
1492 && containsTypeEquivalent(t.elemtype, elemtype(s));
1493 }
1494
1495 @Override
1496 public Boolean visitMethodType(MethodType t, Type s) {
1497 // isSameType for methods does not take thrown
1498 // exceptions into account!
1499 return hasSameArgs(t, s) && visit(t.getReturnType(), s.getReturnType());
1500 }
1501
1621 // void debugContainsType(WildcardType t, Type s) {
1622 // System.err.println();
1623 // System.err.format(" does %s contain %s?%n", t, s);
1624 // System.err.format(" %s U(%s) <: U(%s) %s = %s%n",
1625 // wildUpperBound(s), s, t, wildUpperBound(t),
1626 // t.isSuperBound()
1627 // || isSubtypeNoCapture(wildUpperBound(s), wildUpperBound(t)));
1628 // System.err.format(" %s L(%s) <: L(%s) %s = %s%n",
1629 // wildLowerBound(t), t, s, wildLowerBound(s),
1630 // t.isExtendsBound()
1631 // || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s)));
1632 // System.err.println();
1633 // }
1634
1635 @Override
1636 public Boolean visitWildcardType(WildcardType t, Type s) {
1637 if (s.isPartial())
1638 return containedBy(s, t);
1639 else {
1640 // debugContainsType(t, s);
1641
1642 // ----------------------------------- Unspecified behavior ----------------
1643
1644 /* If a primitive class V implements an interface I, then does "? extends I" contain V?
1645 It seems widening must be applied here to answer yes to compile some common code
1646 patterns.
1647 */
1648
1649 // ---------------------------------------------------------------------------
1650 return isSameWildcard(t, s)
1651 || isCaptureOf(s, t)
1652 || ((t.isExtendsBound() || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s))) &&
1653 (t.isSuperBound() || isSubtypeNoCapture(wildUpperBound(s), wildUpperBound(t))));
1654 }
1655 }
1656
1657 @Override
1658 public Boolean visitUndetVar(UndetVar t, Type s) {
1659 if (!s.hasTag(WILDCARD)) {
1660 return isSameType(t, s);
1661 } else {
1662 return false;
1663 }
1664 }
1665
1666 @Override
1667 public Boolean visitErrorType(ErrorType t, Type s) {
1668 return true;
1669 }
1719 warnStack = warnStack.prepend(warn);
1720 checkUnsafeVarargsConversion(t, s, warn);
1721 result = isCastable.visit(t,s);
1722 } finally {
1723 warnStack = warnStack.tail;
1724 }
1725 } else {
1726 result = isCastable.visit(t,s);
1727 }
1728 if (result && t.hasTag(CLASS) && t.tsym.kind.matches(Kinds.KindSelector.TYP)
1729 && s.hasTag(CLASS) && s.tsym.kind.matches(Kinds.KindSelector.TYP)
1730 && (t.tsym.isSealed() || s.tsym.isSealed())) {
1731 return (t.isCompound() || s.isCompound()) ?
1732 true :
1733 !areDisjoint((ClassSymbol)t.tsym, (ClassSymbol)s.tsym);
1734 }
1735 return result;
1736 }
1737 // where
1738 private boolean areDisjoint(ClassSymbol ts, ClassSymbol ss) {
1739 if (isSubtype(erasure(ts.type.referenceProjectionOrSelf()), erasure(ss.type))) {
1740 return false;
1741 }
1742 // if both are classes or both are interfaces, shortcut
1743 if (ts.isInterface() == ss.isInterface() && isSubtype(erasure(ss.type), erasure(ts.type))) {
1744 return false;
1745 }
1746 if (ts.isInterface() && !ss.isInterface()) {
1747 /* so ts is interface but ss is a class
1748 * an interface is disjoint from a class if the class is disjoint form the interface
1749 */
1750 return areDisjoint(ss, ts);
1751 }
1752 // a final class that is not subtype of ss is disjoint
1753 if (!ts.isInterface() && ts.isFinal()) {
1754 return true;
1755 }
1756 // if at least one is sealed
1757 if (ts.isSealed() || ss.isSealed()) {
1758 // permitted subtypes have to be disjoint with the other symbol
1759 ClassSymbol sealedOne = ts.isSealed() ? ts : ss;
1774 case DOUBLE:
1775 return s.isNumeric();
1776 case BOOLEAN:
1777 return s.hasTag(BOOLEAN);
1778 case VOID:
1779 return false;
1780 case BOT:
1781 return isSubtype(t, s);
1782 default:
1783 throw new AssertionError();
1784 }
1785 }
1786
1787 @Override
1788 public Boolean visitWildcardType(WildcardType t, Type s) {
1789 return isCastable(wildUpperBound(t), s, warnStack.head);
1790 }
1791
1792 @Override
1793 public Boolean visitClassType(ClassType t, Type s) {
1794 if (s.hasTag(ERROR) || (s.hasTag(BOT) && (!allowPrimitiveClasses || !t.isPrimitiveClass())))
1795 return true;
1796
1797 if (s.hasTag(TYPEVAR)) {
1798 if (isCastable(t, s.getUpperBound(), noWarnings)) {
1799 warnStack.head.warn(LintCategory.UNCHECKED);
1800 return true;
1801 } else {
1802 return false;
1803 }
1804 }
1805
1806 if (t.isCompound() || s.isCompound()) {
1807 return !t.isCompound() ?
1808 visitCompoundType((ClassType)s, t, true) :
1809 visitCompoundType(t, s, false);
1810 }
1811
1812 if (s.hasTag(CLASS) || s.hasTag(ARRAY)) {
1813 if (allowPrimitiveClasses) {
1814 if (t.isPrimitiveClass()) {
1815 // (s) Value ? == (s) Value.ref
1816 t = t.referenceProjection();
1817 }
1818 if (s.isPrimitiveClass()) {
1819 // (Value) t ? == (Value.ref) t
1820 s = s.referenceProjection();
1821 }
1822 }
1823 boolean upcast;
1824 if ((upcast = isSubtype(erasure(t), erasure(s)))
1825 || isSubtype(erasure(s), erasure(t))) {
1826 if (!upcast && s.hasTag(ARRAY)) {
1827 if (!isReifiable(s))
1828 warnStack.head.warn(LintCategory.UNCHECKED);
1829 return true;
1830 } else if (s.isRaw()) {
1831 return true;
1832 } else if (t.isRaw()) {
1833 if (!isUnbounded(s))
1834 warnStack.head.warn(LintCategory.UNCHECKED);
1835 return true;
1836 }
1837 // Assume |a| <: |b|
1838 final Type a = upcast ? t : s;
1839 final Type b = upcast ? s : t;
1840 final boolean HIGH = true;
1841 final boolean LOW = false;
1842 final boolean DONT_REWRITE_TYPEVARS = false;
2196 * @return the ArrayType for the given component
2197 */
2198 public ArrayType makeArrayType(Type t) {
2199 if (t.hasTag(VOID) || t.hasTag(PACKAGE)) {
2200 Assert.error("Type t must not be a VOID or PACKAGE type, " + t.toString());
2201 }
2202 return new ArrayType(t, syms.arrayClass);
2203 }
2204 // </editor-fold>
2205
2206 // <editor-fold defaultstate="collapsed" desc="asSuper">
2207 /**
2208 * Return the (most specific) base type of t that starts with the
2209 * given symbol. If none exists, return null.
2210 *
2211 * Caveat Emptor: Since javac represents the class of all arrays with a singleton
2212 * symbol Symtab.arrayClass, which by being a singleton cannot hold any discriminant,
2213 * this method could yield surprising answers when invoked on arrays. For example when
2214 * invoked with t being byte [] and sym being t.sym itself, asSuper would answer null.
2215 *
2216 * Further caveats in Valhalla: There are two "hazards" we need to watch out for when using
2217 * this method.
2218 *
2219 * 1. Since Foo.ref and Foo.val share the same symbol, that of Foo.class, a call to
2220 * asSuper(Foo.ref.type, Foo.val.type.tsym) would return non-null. This MAY NOT BE correct
2221 * depending on the call site. Foo.val is NOT a super type of Foo.ref either in the language
2222 * model or in the VM's world view. An example of such an hazardous call used to exist in
2223 * Gen.visitTypeCast. When we emit code for (Foo) Foo.ref.instance a check for whether we
2224 * really need the cast cannot/shouldn't be gated on
2225 *
2226 * asSuper(tree.expr.type, tree.clazz.type.tsym) == null)
2227 *
2228 * but use !types.isSubtype(tree.expr.type, tree.clazz.type) which operates in terms of
2229 * types. When we operate in terms of symbols, there is a loss of type information leading
2230 * to a hazard. Whether a call to asSuper should be transformed into a isSubtype call is
2231 * tricky. isSubtype returns just a boolean while asSuper returns richer information which
2232 * may be required at the call site. Also where the concerned symbol corresponds to a
2233 * generic class, an asSuper call cannot be conveniently rewritten as an isSubtype call
2234 * (see that asSuper(ArrayList<String>.type, List<T>.tsym) != null while
2235 * isSubType(ArrayList<String>.type, List<T>.type) is false;) So care needs to be exercised.
2236 *
2237 * 2. Given a primitive class Foo, a call to asSuper(Foo.type, SuperclassOfFoo.tsym) and/or
2238 * a call to asSuper(Foo.type, SuperinterfaceOfFoo.tsym) would answer null. In many places
2239 * that is NOT what we want. An example of such a hazardous call used to occur in
2240 * Attr.visitForeachLoop when checking to make sure the for loop's control variable of a type
2241 * that implements Iterable: viz: types.asSuper(exprType, syms.iterableType.tsym);
2242 * These hazardous calls should be rewritten as
2243 * types.asSuper(exprType.referenceProjectionOrSelf(), syms.iterableType.tsym); instead.
2244 *
2245 * @param t a type
2246 * @param sym a symbol
2247 */
2248 public Type asSuper(Type t, Symbol sym) {
2249 /* Some examples:
2250 *
2251 * (Enum<E>, Comparable) => Comparable<E>
2252 * (c.s.s.d.AttributeTree.ValueKind, Enum) => Enum<c.s.s.d.AttributeTree.ValueKind>
2253 * (c.s.s.t.ExpressionTree, c.s.s.t.Tree) => c.s.s.t.Tree
2254 * (j.u.List<capture#160 of ? extends c.s.s.d.DocTree>, Iterable) =>
2255 * Iterable<capture#160 of ? extends c.s.s.d.DocTree>
2256 */
2257
2258 if (allowPrimitiveClasses && t.isPrimitiveClass()) {
2259 // No man may be an island, but the bell tolls for a value.
2260 return t.tsym == sym ? t : null;
2261 }
2262
2263 if (sym.type == syms.objectType) { //optimization
2264 return syms.objectType;
2265 }
2266 return asSuper.visit(t, sym);
2267 }
2268 // where
2269 private SimpleVisitor<Type,Symbol> asSuper = new SimpleVisitor<Type,Symbol>() {
2270
2271 private Set<Symbol> seenTypes = new HashSet<>();
2272
2273 public Type visitType(Type t, Symbol sym) {
2274 return null;
2275 }
2276
2277 @Override
2278 public Type visitClassType(ClassType t, Symbol sym) {
2279 if (t.tsym == sym)
2280 return t;
2281
2282 Symbol c = t.tsym;
2373 case ARRAY:
2374 return isSubtype(t, sym.type) ? sym.type : null;
2375 case TYPEVAR:
2376 return asSuper(t, sym);
2377 case ERROR:
2378 return t;
2379 default:
2380 return null;
2381 }
2382 }
2383 // </editor-fold>
2384
2385 // <editor-fold defaultstate="collapsed" desc="memberType">
2386 /**
2387 * The type of given symbol, seen as a member of t.
2388 *
2389 * @param t a type
2390 * @param sym a symbol
2391 */
2392 public Type memberType(Type t, Symbol sym) {
2393
2394 if ((sym.flags() & STATIC) != 0)
2395 return sym.type;
2396
2397 /* If any primitive class types are involved, switch over to the reference universe,
2398 where the hierarchy is navigable. V and V.ref have identical membership
2399 with no bridging needs.
2400 */
2401 if (allowPrimitiveClasses && t.isPrimitiveClass())
2402 t = t.referenceProjection();
2403
2404 return memberType.visit(t, sym);
2405 }
2406 // where
2407 private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
2408
2409 public Type visitType(Type t, Symbol sym) {
2410 return sym.type;
2411 }
2412
2413 @Override
2414 public Type visitWildcardType(WildcardType t, Symbol sym) {
2415 return memberType(wildUpperBound(t), sym);
2416 }
2417
2418 @Override
2419 public Type visitClassType(ClassType t, Symbol sym) {
2420 Symbol owner = sym.owner;
2421 long flags = sym.flags();
2422 if (((flags & STATIC) == 0) && owner.type.isParameterized()) {
2423 Type base = asOuterSuper(t, owner);
2424 //if t is an intersection type T = CT & I1 & I2 ... & In
2537 }
2538 }
2539
2540 public Type visitType(Type t, Boolean recurse) {
2541 if (t.isPrimitive())
2542 return t; /*fast special case*/
2543 else {
2544 //other cases already handled
2545 return combineMetadata(t, t);
2546 }
2547 }
2548
2549 @Override
2550 public Type visitWildcardType(WildcardType t, Boolean recurse) {
2551 Type erased = erasure(wildUpperBound(t), recurse);
2552 return combineMetadata(erased, t);
2553 }
2554
2555 @Override
2556 public Type visitClassType(ClassType t, Boolean recurse) {
2557 // erasure(projection(primitive)) = projection(erasure(primitive))
2558 Type erased = eraseClassType(t, recurse);
2559 if (erased.hasTag(CLASS) && t.flavor != erased.getFlavor()) {
2560 erased = new ClassType(erased.getEnclosingType(),
2561 List.nil(), erased.tsym,
2562 erased.getMetadata(), t.flavor);
2563 }
2564 return erased;
2565 }
2566 // where
2567 private Type eraseClassType(ClassType t, Boolean recurse) {
2568 Type erased = t.tsym.erasure(Types.this);
2569 if (recurse) {
2570 erased = new ErasedClassType(erased.getEnclosingType(), erased.tsym,
2571 t.dropMetadata(Annotations.class).getMetadata());
2572 return erased;
2573 } else {
2574 return combineMetadata(erased, t);
2575 }
2576 }
2577
2578 @Override
2579 public Type visitTypeVar(TypeVar t, Boolean recurse) {
2580 Type erased = erasure(t.getUpperBound(), recurse);
2581 return combineMetadata(erased, t);
2582 }
2583 };
2584
2585 public List<Type> erasure(List<Type> ts) {
2586 return erasure.visit(ts, false);
2587 }
2588
2589 public Type erasureRecursive(Type t) {
2590 return erasure(t, true);
2591 }
2592
2593 public List<Type> erasureRecursive(List<Type> ts) {
2594 return erasure.visit(ts, true);
2595 }
2596 // </editor-fold>
2876 /**
2877 * If the given type is a (possibly selected) type variable,
2878 * return the bounding class of this type, otherwise return the
2879 * type itself.
2880 */
2881 public Type classBound(Type t) {
2882 return classBound.visit(t);
2883 }
2884 // where
2885 private UnaryVisitor<Type> classBound = new UnaryVisitor<Type>() {
2886
2887 public Type visitType(Type t, Void ignored) {
2888 return t;
2889 }
2890
2891 @Override
2892 public Type visitClassType(ClassType t, Void ignored) {
2893 Type outer1 = classBound(t.getEnclosingType());
2894 if (outer1 != t.getEnclosingType())
2895 return new ClassType(outer1, t.getTypeArguments(), t.tsym,
2896 t.getMetadata(), t.getFlavor());
2897 else
2898 return t;
2899 }
2900
2901 @Override
2902 public Type visitTypeVar(TypeVar t, Void ignored) {
2903 return classBound(supertype(t));
2904 }
2905
2906 @Override
2907 public Type visitErrorType(ErrorType t, Void ignored) {
2908 return t;
2909 }
2910 };
2911 // </editor-fold>
2912
2913 // <editor-fold defaultstate="collapsed" desc="subsignature / override equivalence">
2914 /**
2915 * Returns true iff the first signature is a <em>subsignature</em>
2916 * of the other. This is <b>not</b> an equivalence
3997 m = new WildcardType(lub(wildUpperBound(act1.head),
3998 wildUpperBound(act2.head)),
3999 BoundKind.EXTENDS,
4000 syms.boundClass);
4001 mergeCache.remove(pair);
4002 } else {
4003 m = new WildcardType(syms.objectType,
4004 BoundKind.UNBOUND,
4005 syms.boundClass);
4006 }
4007 merged.append(m.withTypeVar(typarams.head));
4008 }
4009 act1 = act1.tail;
4010 act2 = act2.tail;
4011 typarams = typarams.tail;
4012 }
4013 Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
4014 // There is no spec detailing how type annotations are to
4015 // be inherited. So set it to noAnnotations for now
4016 return new ClassType(class1.getEnclosingType(), merged.toList(),
4017 class1.tsym, List.nil(), class1.getFlavor());
4018 }
4019
4020 /**
4021 * Return the minimum type of a closure, a compound type if no
4022 * unique minimum exists.
4023 */
4024 private Type compoundMin(List<Type> cl) {
4025 if (cl.isEmpty()) return syms.objectType;
4026 List<Type> compound = closureMin(cl);
4027 if (compound.isEmpty())
4028 return null;
4029 else if (compound.tail.isEmpty())
4030 return compound.head;
4031 else
4032 return makeIntersectionType(compound);
4033 }
4034
4035 /**
4036 * Return the minimum types of a closure, suitable for computing
4037 * compoundMin or glb.
4557 Si.lower = Ti.getSuperBound();
4558 break;
4559 }
4560 Type tmpBound = Si.getUpperBound().hasTag(UNDETVAR) ? ((UndetVar)Si.getUpperBound()).qtype : Si.getUpperBound();
4561 Type tmpLower = Si.lower.hasTag(UNDETVAR) ? ((UndetVar)Si.lower).qtype : Si.lower;
4562 if (!Si.getUpperBound().hasTag(ERROR) &&
4563 !Si.lower.hasTag(ERROR) &&
4564 isSameType(tmpBound, tmpLower)) {
4565 currentS.head = Si.getUpperBound();
4566 }
4567 }
4568 currentA = currentA.tail;
4569 currentT = currentT.tail;
4570 currentS = currentS.tail;
4571 }
4572 if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty())
4573 return erasure(t); // some "rare" type involved
4574
4575 if (captured)
4576 return new ClassType(cls.getEnclosingType(), S, cls.tsym,
4577 cls.getMetadata(), cls.getFlavor());
4578 else
4579 return t;
4580 }
4581 // where
4582 public List<Type> freshTypeVariables(List<Type> types) {
4583 ListBuffer<Type> result = new ListBuffer<>();
4584 for (Type t : types) {
4585 if (t.hasTag(WILDCARD)) {
4586 Type bound = ((WildcardType)t).getExtendsBound();
4587 if (bound == null)
4588 bound = syms.objectType;
4589 result.append(new CapturedType(capturedName,
4590 syms.noSymbol,
4591 bound,
4592 syms.botType,
4593 (WildcardType)t));
4594 } else {
4595 result.append(t);
4596 }
4597 }
4968 private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
4969 if (bound.hasTag(BOT)) {
4970 return new WildcardType(syms.objectType,
4971 BoundKind.UNBOUND,
4972 syms.boundClass,
4973 formal);
4974 } else {
4975 return new WildcardType(bound,
4976 BoundKind.SUPER,
4977 syms.boundClass,
4978 formal);
4979 }
4980 }
4981
4982 /**
4983 * A wrapper for a type that allows use in sets.
4984 */
4985 public static class UniqueType {
4986 public final Type type;
4987 final Types types;
4988 private boolean encodeTypeSig;
4989
4990 public UniqueType(Type type, Types types, boolean encodeTypeSig) {
4991 this.type = type;
4992 this.types = types;
4993 this.encodeTypeSig = encodeTypeSig;
4994 }
4995
4996 public UniqueType(Type type, Types types) {
4997 this(type, types, true);
4998 }
4999
5000 public int hashCode() {
5001 return types.hashCode(type);
5002 }
5003
5004 public boolean equals(Object obj) {
5005 return (obj instanceof UniqueType uniqueType) &&
5006 types.isSameType(type, uniqueType.type);
5007 }
5008
5009 public boolean encodeTypeSig() {
5010 return encodeTypeSig;
5011 }
5012
5013 public String toString() {
5014 return type.toString();
5015 }
5016
5017 }
5018 // </editor-fold>
5019
5020 // <editor-fold defaultstate="collapsed" desc="Visitors">
5021 /**
5022 * A default visitor for types. All visitor methods except
5023 * visitType are implemented by delegating to visitType. Concrete
5024 * subclasses must provide an implementation of visitType and can
5025 * override other methods as needed.
5026 *
5027 * @param <R> the return type of the operation implemented by this
5028 * visitor; use Void if no return type is needed.
5029 * @param <S> the type of the second argument (the first being the
5030 * type itself) of the operation implemented by this visitor; use
5031 * Void if a second argument is not needed.
5032 */
5231 break;
5232 case LONG:
5233 append('J');
5234 break;
5235 case FLOAT:
5236 append('F');
5237 break;
5238 case DOUBLE:
5239 append('D');
5240 break;
5241 case BOOLEAN:
5242 append('Z');
5243 break;
5244 case VOID:
5245 append('V');
5246 break;
5247 case CLASS:
5248 if (type.isCompound()) {
5249 reportIllegalSignature(type);
5250 }
5251 if (types.allowPrimitiveClasses && type.isPrimitiveClass())
5252 append('Q');
5253 else
5254 append('L');
5255 assembleClassSig(type);
5256 append(';');
5257 break;
5258 case ARRAY:
5259 ArrayType at = (ArrayType) type;
5260 append('[');
5261 assembleSig(at.elemtype);
5262 break;
5263 case METHOD:
5264 MethodType mt = (MethodType) type;
5265 append('(');
5266 assembleSig(mt.argtypes);
5267 append(')');
5268 assembleSig(mt.restype);
5269 if (hasTypeVar(mt.thrown)) {
5270 for (List<Type> l = mt.thrown; l.nonEmpty(); l = l.tail) {
5271 append('^');
5272 assembleSig(l.head);
5273 }
5274 }
|