< prev index next >

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

Print this page

  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  *

  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 boolean allowDefaultMethods;
  96     final boolean mapCapturesToBounds;

  97     final Check chk;
  98     final Enter enter;
  99     JCDiagnostic.Factory diags;
 100     List<Warner> warnStack = List.nil();
 101     final Name capturedName;
 102 
 103     public final Warner noWarnings;
 104 
 105     // <editor-fold defaultstate="collapsed" desc="Instantiating">
 106     public static Types instance(Context context) {
 107         Types instance = context.get(typesKey);
 108         if (instance == null)
 109             instance = new Types(context);
 110         return instance;
 111     }
 112 
 113     protected Types(Context context) {
 114         context.put(typesKey, this);
 115         syms = Symtab.instance(context);
 116         names = Names.instance(context);
 117         Source source = Source.instance(context);
 118         allowDefaultMethods = Feature.DEFAULT_METHODS.allowedInSource(source);
 119         mapCapturesToBounds = Feature.MAP_CAPTURES_TO_BOUNDS.allowedInSource(source);
 120         chk = Check.instance(context);
 121         enter = Enter.instance(context);
 122         capturedName = names.fromString("<captured wildcard>");
 123         messages = JavacMessages.instance(context);
 124         diags = JCDiagnostic.Factory.instance(context);
 125         noWarnings = new Warner(null);


 126     }
 127     // </editor-fold>
 128 
 129     // <editor-fold defaultstate="collapsed" desc="bounds">
 130     /**
 131      * Get a wildcard's upper bound, returning non-wildcards unchanged.
 132      * @param t a type argument, either a wildcard or a type
 133      */
 134     public Type wildUpperBound(Type t) {
 135         if (t.hasTag(WILDCARD)) {
 136             WildcardType w = (WildcardType) t;
 137             if (w.isSuperBound())
 138                 return w.bound == null ? syms.objectType : w.bound.getUpperBound();
 139             else
 140                 return wildUpperBound(w.type);
 141         }
 142         else return t;
 143     }
 144 
 145     /**

 254                 if (components == components1) return t;
 255                 else return makeIntersectionType(components1);
 256             } else {
 257                 Type outer = t.getEnclosingType();
 258                 Type outer1 = visit(outer, pkind);
 259                 List<Type> typarams = t.getTypeArguments();
 260                 List<Type> formals = t.tsym.type.getTypeArguments();
 261                 ListBuffer<Type> typarams1 = new ListBuffer<>();
 262                 boolean changed = false;
 263                 for (Type actual : typarams) {
 264                     Type t2 = mapTypeArgument(t, formals.head.getUpperBound(), actual, pkind);
 265                     if (t2.hasTag(BOT)) {
 266                         //not defined
 267                         return syms.botType;
 268                     }
 269                     typarams1.add(t2);
 270                     changed |= actual != t2;
 271                     formals = formals.tail;
 272                 }
 273                 if (outer1 == outer && !changed) return t;
 274                 else return new ClassType(outer1, typarams1.toList(), t.tsym, t.getMetadata()) {
 275                     @Override
 276                     protected boolean needsStripping() {
 277                         return true;
 278                     }
 279                 };
 280             }
 281         }
 282 
 283         @Override
 284         public Type visitArrayType(ArrayType t, ProjectionKind s) {
 285             Type elemtype = t.elemtype;
 286             Type elemtype1 = visit(elemtype, s);
 287             if (elemtype1 == elemtype) {
 288                 return t;
 289             } else if (elemtype1.hasTag(BOT)) {
 290                 //undefined
 291                 return syms.botType;
 292             } else {
 293                 return new ArrayType(elemtype1, t.tsym, t.metadata) {
 294                     @Override

 585                 }
 586                 return res;
 587             }
 588 
 589             @Override
 590             public Type visitErrorType(ErrorType t, Symbol sym) {
 591                 return t;
 592             }
 593         };
 594     // </editor-fold>
 595 
 596     // <editor-fold defaultstate="collapsed" desc="isConvertible">
 597     /**
 598      * Is t a subtype of or convertible via boxing/unboxing
 599      * conversion to s?
 600      */
 601     public boolean isConvertible(Type t, Type s, Warner warn) {
 602         if (t.hasTag(ERROR)) {
 603             return true;
 604         }









 605         boolean tPrimitive = t.isPrimitive();
 606         boolean sPrimitive = s.isPrimitive();
 607         if (tPrimitive == sPrimitive) {
 608             return isSubtypeUnchecked(t, s, warn);
 609         }
 610         boolean tUndet = t.hasTag(UNDETVAR);
 611         boolean sUndet = s.hasTag(UNDETVAR);
 612 
 613         if (tUndet || sUndet) {
 614             return tUndet ?
 615                     isSubtype(t, boxedTypeOrType(s)) :
 616                     isSubtype(boxedTypeOrType(t), s);
 617         }
 618 
 619         return tPrimitive
 620             ? isSubtype(boxedClass(t).type, s)
 621             : isSubtype(unboxedType(t), s);
 622     }
 623 
 624     /**

 741                 Type mtype = memberType(origin.type, sym);
 742                 if (abstracts.isEmpty()) {
 743                     abstracts.append(sym);
 744                 } else if ((sym.name == abstracts.first().name &&
 745                         overrideEquivalent(mtype, memberType(origin.type, abstracts.first())))) {
 746                     if (!abstracts.stream().filter(msym -> msym.owner.isSubClass(sym.enclClass(), Types.this))
 747                             .map(msym -> memberType(origin.type, msym))
 748                             .anyMatch(abstractMType -> isSubSignature(abstractMType, mtype))) {
 749                         abstracts.append(sym);
 750                     }
 751                 } else {
 752                     //the target method(s) should be the only abstract members of t
 753                     throw failure("not.a.functional.intf.1",  origin,
 754                             diags.fragment(Fragments.IncompatibleAbstracts(Kinds.kindName(origin), origin)));
 755                 }
 756             }
 757             if (abstracts.isEmpty()) {
 758                 //t must define a suitable non-generic method
 759                 throw failure("not.a.functional.intf.1", origin,
 760                             diags.fragment(Fragments.NoAbstracts(Kinds.kindName(origin), origin)));
 761             } else if (abstracts.size() == 1) {
 762                 return new FunctionDescriptor(abstracts.first());


 763             } else { // size > 1
 764                 FunctionDescriptor descRes = mergeDescriptors(origin, abstracts.toList());
 765                 if (descRes == null) {
 766                     //we can get here if the functional interface is ill-formed
 767                     ListBuffer<JCDiagnostic> descriptors = new ListBuffer<>();
 768                     for (Symbol desc : abstracts) {
 769                         String key = desc.type.getThrownTypes().nonEmpty() ?
 770                                 "descriptor.throws" : "descriptor";
 771                         descriptors.append(diags.fragment(key, desc.name,
 772                                 desc.type.getParameterTypes(),
 773                                 desc.type.getReturnType(),
 774                                 desc.type.getThrownTypes()));
 775                     }
 776                     JCDiagnostic msg =
 777                             diags.fragment(Fragments.IncompatibleDescsInFunctionalIntf(Kinds.kindName(origin),
 778                                                                                        origin));
 779                     JCDiagnostic.MultilineDiagnostic incompatibleDescriptors =
 780                             new JCDiagnostic.MultilineDiagnostic(msg, descriptors.toList());
 781                     throw failure(incompatibleDescriptors);
 782                 }
 783                 return descRes;
 784             }











 785         }
 786 
 787         /**
 788          * Compute a synthetic type for the target descriptor given a list
 789          * of override-equivalent methods in the functional interface type.
 790          * The resulting method type is a method type that is override-equivalent
 791          * and return-type substitutable with each method in the original list.
 792          */
 793         private FunctionDescriptor mergeDescriptors(TypeSymbol origin, List<Symbol> methodSyms) {
 794             return mergeAbstracts(methodSyms, origin.type, false)
 795                     .map(bestSoFar -> new FunctionDescriptor(bestSoFar.baseSymbol()) {
 796                         @Override
 797                         public Type getType(Type origin) {
 798                             Type mt = memberType(origin, getSymbol());
 799                             return createMethodTypeWithThrown(mt, bestSoFar.type.getThrownTypes());
 800                         }
 801                     }).orElse(null);
 802         }
 803 
 804         FunctionDescriptorLookupError failure(String msg, Object... args) {

1004      */
1005     public boolean isSubtypeUnchecked(Type t, Type s) {
1006         return isSubtypeUnchecked(t, s, noWarnings);
1007     }
1008     /**
1009      * Is t an unchecked subtype of s?
1010      */
1011     public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) {
1012         boolean result = isSubtypeUncheckedInternal(t, s, true, warn);
1013         if (result) {
1014             checkUnsafeVarargsConversion(t, s, warn);
1015         }
1016         return result;
1017     }
1018     //where
1019         private boolean isSubtypeUncheckedInternal(Type t, Type s, boolean capture, Warner warn) {
1020             if (t.hasTag(ARRAY) && s.hasTag(ARRAY)) {
1021                 if (((ArrayType)t).elemtype.isPrimitive()) {
1022                     return isSameType(elemtype(t), elemtype(s));
1023                 } else {
1024                     return isSubtypeUncheckedInternal(elemtype(t), elemtype(s), false, warn);










1025                 }
1026             } else if (isSubtype(t, s, capture)) {
1027                 return true;
1028             } else if (t.hasTag(TYPEVAR)) {
1029                 return isSubtypeUncheckedInternal(t.getUpperBound(), s, false, warn);
1030             } else if (!s.isRaw()) {
1031                 Type t2 = asSuper(t, s.tsym);
1032                 if (t2 != null && t2.isRaw()) {
1033                     if (isReifiable(s)) {
1034                         warn.silentWarn(LintCategory.UNCHECKED);
1035                     } else {
1036                         warn.warn(LintCategory.UNCHECKED);
1037                     }
1038                     return true;
1039                 }
1040             }
1041             return false;
1042         }
1043 
1044         private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) {

1101     }
1102     // where
1103         private TypeRelation isSubtype = new TypeRelation()
1104         {
1105             @Override
1106             public Boolean visitType(Type t, Type s) {
1107                 switch (t.getTag()) {
1108                  case BYTE:
1109                      return (!s.hasTag(CHAR) && t.getTag().isSubRangeOf(s.getTag()));
1110                  case CHAR:
1111                      return (!s.hasTag(SHORT) && t.getTag().isSubRangeOf(s.getTag()));
1112                  case SHORT: case INT: case LONG:
1113                  case FLOAT: case DOUBLE:
1114                      return t.getTag().isSubRangeOf(s.getTag());
1115                  case BOOLEAN: case VOID:
1116                      return t.hasTag(s.getTag());
1117                  case TYPEVAR:
1118                      return isSubtypeNoCapture(t.getUpperBound(), s);
1119                  case BOT:
1120                      return
1121                          s.hasTag(BOT) || s.hasTag(CLASS) ||
1122                          s.hasTag(ARRAY) || s.hasTag(TYPEVAR);
1123                  case WILDCARD: //we shouldn't be here - avoids crash (see 7034495)
1124                  case NONE:
1125                      return false;
1126                  default:
1127                      throw new AssertionError("isSubtype " + t.getTag());
1128                  }
1129             }
1130 
1131             private Set<TypePair> cache = new HashSet<>();
1132 
1133             private boolean containsTypeRecursive(Type t, Type s) {
1134                 TypePair pair = new TypePair(t, s);
1135                 if (cache.add(pair)) {
1136                     try {
1137                         return containsType(t.getTypeArguments(),
1138                                             s.getTypeArguments());
1139                     } finally {
1140                         cache.remove(pair);
1141                     }

1168                                              BoundKind.EXTENDS,
1169                                              syms.boundClass,
1170                                              s.getMetadata());
1171                         changed = true;
1172                     }
1173                     rewrite.append(s);
1174                 }
1175                 if (changed)
1176                     return subst(t.tsym.type, from.toList(), rewrite.toList());
1177                 else
1178                     return t;
1179             }
1180 
1181             @Override
1182             public Boolean visitClassType(ClassType t, Type s) {
1183                 Type sup = asSuper(t, s.tsym);
1184                 if (sup == null) return false;
1185                 // If t is an intersection, sup might not be a class type
1186                 if (!sup.hasTag(CLASS)) return isSubtypeNoCapture(sup, s);
1187                 return sup.tsym == s.tsym

1188                      // Check type variable containment
1189                     && (!s.isParameterized() || containsTypeRecursive(s, sup))
1190                     && isSubtypeNoCapture(sup.getEnclosingType(),
1191                                           s.getEnclosingType());
1192             }
1193 
1194             @Override
1195             public Boolean visitArrayType(ArrayType t, Type s) {
1196                 if (s.hasTag(ARRAY)) {
1197                     if (t.elemtype.isPrimitive())
1198                         return isSameType(t.elemtype, elemtype(s));
1199                     else
1200                         return isSubtypeNoCapture(t.elemtype, elemtype(s));









1201                 }
1202 
1203                 if (s.hasTag(CLASS)) {
1204                     Name sname = s.tsym.getQualifiedName();
1205                     return sname == names.java_lang_Object
1206                         || sname == names.java_lang_Cloneable
1207                         || sname == names.java_io_Serializable;
1208                 }
1209 
1210                 return false;
1211             }
1212 
1213             @Override
1214             public Boolean visitUndetVar(UndetVar t, Type s) {
1215                 //todo: test against origin needed? or replace with substitution?
1216                 if (t == s || t.qtype == s || s.hasTag(ERROR) || s.hasTag(UNKNOWN)) {
1217                     return true;
1218                 } else if (s.hasTag(BOT)) {
1219                     //if 's' is 'null' there's no instantiated type U for which
1220                     //U <: s (but 'null' itself, which is not a valid type)

1403                     if (!visit(supertype(t), supertype(s)))
1404                         return false;
1405 
1406                     Map<Symbol,Type> tMap = new HashMap<>();
1407                     for (Type ti : interfaces(t)) {
1408                         if (tMap.containsKey(ti)) {
1409                             throw new AssertionError("Malformed intersection");
1410                         }
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;

1833 
1834             @Override
1835             public Boolean visitArrayType(ArrayType t, Type s) {
1836                 switch (s.getTag()) {
1837                 case ERROR:
1838                 case BOT:
1839                     return true;
1840                 case TYPEVAR:
1841                     if (isCastable(s, t, noWarnings)) {
1842                         warnStack.head.warn(LintCategory.UNCHECKED);
1843                         return true;
1844                     } else {
1845                         return false;
1846                     }
1847                 case CLASS:
1848                     return isSubtype(t, s);
1849                 case ARRAY:
1850                     if (elemtype(t).isPrimitive() || elemtype(s).isPrimitive()) {
1851                         return elemtype(t).hasTag(elemtype(s).getTag());
1852                     } else {
1853                         return visit(elemtype(t), elemtype(s));




1854                     }
1855                 default:
1856                     return false;
1857                 }
1858             }
1859 
1860             @Override
1861             public Boolean visitTypeVar(TypeVar t, Type s) {
1862                 switch (s.getTag()) {
1863                 case ERROR:
1864                 case BOT:
1865                     return true;
1866                 case TYPEVAR:
1867                     if (isSubtype(t, s)) {
1868                         return true;
1869                     } else if (isCastable(t.getUpperBound(), s, noWarnings)) {
1870                         warnStack.head.warn(LintCategory.UNCHECKED);
1871                         return true;
1872                     } else {
1873                         return 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;

2197 
2198             @Override
2199             public Type visitArrayType(ArrayType t, Symbol sym) {
2200                 return isSubtype(t, sym.type) ? sym.type : null;
2201             }
2202 
2203             @Override
2204             public Type visitTypeVar(TypeVar t, Symbol sym) {
2205                 if (t.tsym == sym)
2206                     return t;
2207                 else
2208                     return asSuper(t.getUpperBound(), sym);
2209             }
2210 
2211             @Override
2212             public Type visitErrorType(ErrorType t, Symbol sym) {
2213                 return t;
2214             }
2215         };
2216 






































































2217     /**
2218      * Return the base type of t or any of its outer types that starts
2219      * with the given symbol.  If none exists, return null.
2220      *
2221      * @param t a type
2222      * @param sym a symbol
2223      */
2224     public Type asOuterSuper(Type t, Symbol sym) {
2225         switch (t.getTag()) {
2226         case CLASS:
2227             do {
2228                 Type s = asSuper(t, sym);
2229                 if (s != null) return s;
2230                 t = t.getEnclosingType();
2231             } while (t.hasTag(CLASS));
2232             return null;
2233         case ARRAY:
2234             return isSubtype(t, sym.type) ? sym.type : null;
2235         case TYPEVAR:
2236             return asSuper(t, sym);

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.getMetadata().without(Kind.ANNOTATIONS));
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>

2475      */
2476     public IntersectionClassType makeIntersectionType(List<Type> bounds) {
2477         return makeIntersectionType(bounds, bounds.head.tsym.isInterface());
2478     }
2479 
2480     /**
2481      * Make an intersection type from non-empty list of types.  The list should be ordered according to
2482      * {@link TypeSymbol#precedes(TypeSymbol, Types)}. This does not cause symbol completion as
2483      * an extra parameter indicates as to whether all bounds are interfaces - in which case the
2484      * supertype is implicitly assumed to be 'Object'.
2485      *
2486      * @param bounds        the types from which the intersection type is formed
2487      * @param allInterfaces are all bounds interface types?
2488      */
2489     public IntersectionClassType makeIntersectionType(List<Type> bounds, boolean allInterfaces) {
2490         Assert.check(bounds.nonEmpty());
2491         Type firstExplicitBound = bounds.head;
2492         if (allInterfaces) {
2493             bounds = bounds.prepend(syms.objectType);
2494         }

2495         ClassSymbol bc =
2496             new ClassSymbol(ABSTRACT|PUBLIC|SYNTHETIC|COMPOUND|ACYCLIC,
2497                             Type.moreInfo
2498                                 ? names.fromString(bounds.toString())
2499                                 : names.empty,
2500                             null,
2501                             syms.noSymbol);
2502         IntersectionClassType intersectionType = new IntersectionClassType(bounds, bc, allInterfaces);
2503         bc.type = intersectionType;
2504         bc.erasure_field = (bounds.head.hasTag(TYPEVAR)) ?
2505                 syms.objectType : // error condition, recover
2506                 erasure(firstExplicitBound);
2507         bc.members_field = WriteableScope.create(bc);
2508         return intersectionType;
2509     }
2510     // </editor-fold>
2511 
2512     // <editor-fold defaultstate="collapsed" desc="supertype">
2513     public Type supertype(Type t) {
2514         return supertype.visit(t);
2515     }
2516     // where

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="sub signature / override equivalence">
2784     /**
2785      * Returns true iff the first signature is a <em>sub
2786      * signature</em> of the other.  This is <b>not</b> an equivalence

3873                         m = new WildcardType(lub(wildUpperBound(act1.head),
3874                                                  wildUpperBound(act2.head)),
3875                                              BoundKind.EXTENDS,
3876                                              syms.boundClass);
3877                         mergeCache.remove(pair);
3878                     } else {
3879                         m = new WildcardType(syms.objectType,
3880                                              BoundKind.UNBOUND,
3881                                              syms.boundClass);
3882                     }
3883                     merged.append(m.withTypeVar(typarams.head));
3884                 }
3885                 act1 = act1.tail;
3886                 act2 = act2.tail;
3887                 typarams = typarams.tail;
3888             }
3889             Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
3890             // There is no spec detailing how type annotations are to
3891             // be inherited.  So set it to noAnnotations for now
3892             return new ClassType(class1.getEnclosingType(), merged.toList(),
3893                                  class1.tsym);
3894         }
3895 
3896     /**
3897      * Return the minimum type of a closure, a compound type if no
3898      * unique minimum exists.
3899      */
3900     private Type compoundMin(List<Type> cl) {
3901         if (cl.isEmpty()) return syms.objectType;
3902         List<Type> compound = closureMin(cl);
3903         if (compound.isEmpty())
3904             return null;
3905         else if (compound.tail.isEmpty())
3906             return compound.head;
3907         else
3908             return makeIntersectionType(compound);
3909     }
3910 
3911     /**
3912      * Return the minimum types of a closure, suitable for computing
3913      * compoundMin or glb.

3945     }
3946 
3947     /**
3948      * Return the least upper bound of list of types.  if the lub does
3949      * not exist return null.
3950      */
3951     public Type lub(List<Type> ts) {
3952         return lub(ts.toArray(new Type[ts.length()]));
3953     }
3954 
3955     /**
3956      * Return the least upper bound (lub) of set of types.  If the lub
3957      * does not exist return the type of null (bottom).
3958      */
3959     public Type lub(Type... ts) {
3960         final int UNKNOWN_BOUND = 0;
3961         final int ARRAY_BOUND = 1;
3962         final int CLASS_BOUND = 2;
3963 
3964         int[] kinds = new int[ts.length];
3965 
3966         int boundkind = UNKNOWN_BOUND;
3967         for (int i = 0 ; i < ts.length ; i++) {
3968             Type t = ts[i];
3969             switch (t.getTag()) {
3970             case CLASS:
3971                 boundkind |= kinds[i] = CLASS_BOUND;
3972                 break;
3973             case ARRAY:
3974                 boundkind |= kinds[i] = ARRAY_BOUND;
3975                 break;
3976             case  TYPEVAR:
3977                 do {
3978                     t = t.getUpperBound();
3979                 } while (t.hasTag(TYPEVAR));
3980                 if (t.hasTag(ARRAY)) {
3981                     boundkind |= kinds[i] = ARRAY_BOUND;
3982                 } else {
3983                     boundkind |= kinds[i] = CLASS_BOUND;
3984                 }
3985                 break;

4433                     Si.lower = Ti.getSuperBound();
4434                     break;
4435                 }
4436                 Type tmpBound = Si.getUpperBound().hasTag(UNDETVAR) ? ((UndetVar)Si.getUpperBound()).qtype : Si.getUpperBound();
4437                 Type tmpLower = Si.lower.hasTag(UNDETVAR) ? ((UndetVar)Si.lower).qtype : Si.lower;
4438                 if (!Si.getUpperBound().hasTag(ERROR) &&
4439                     !Si.lower.hasTag(ERROR) &&
4440                     isSameType(tmpBound, tmpLower)) {
4441                     currentS.head = Si.getUpperBound();
4442                 }
4443             }
4444             currentA = currentA.tail;
4445             currentT = currentT.tail;
4446             currentS = currentS.tail;
4447         }
4448         if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty())
4449             return erasure(t); // some "rare" type involved
4450 
4451         if (captured)
4452             return new ClassType(cls.getEnclosingType(), S, cls.tsym,
4453                                  cls.getMetadata());
4454         else
4455             return t;
4456     }
4457     // where
4458         public List<Type> freshTypeVariables(List<Type> types) {
4459             ListBuffer<Type> result = new ListBuffer<>();
4460             for (Type t : types) {
4461                 if (t.hasTag(WILDCARD)) {
4462                     Type bound = ((WildcardType)t).getExtendsBound();
4463                     if (bound == null)
4464                         bound = syms.objectType;
4465                     result.append(new CapturedType(capturedName,
4466                                                    syms.noSymbol,
4467                                                    bound,
4468                                                    syms.botType,
4469                                                    (WildcardType)t));
4470                 } else {
4471                     result.append(t);
4472                 }
4473             }

4844     private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
4845         if (bound.hasTag(BOT)) {
4846             return new WildcardType(syms.objectType,
4847                                     BoundKind.UNBOUND,
4848                                     syms.boundClass,
4849                                     formal);
4850         } else {
4851             return new WildcardType(bound,
4852                                     BoundKind.SUPER,
4853                                     syms.boundClass,
4854                                     formal);
4855         }
4856     }
4857 
4858     /**
4859      * A wrapper for a type that allows use in sets.
4860      */
4861     public static class UniqueType {
4862         public final Type type;
4863         final Types types;

4864 
4865         public UniqueType(Type type, Types types) {
4866             this.type = type;
4867             this.types = types;





4868         }
4869 
4870         public int hashCode() {
4871             return types.hashCode(type);
4872         }
4873 
4874         public boolean equals(Object obj) {
4875             return (obj instanceof UniqueType uniqueType) &&
4876                     types.isSameType(type, uniqueType.type);
4877         }
4878 




4879         public String toString() {
4880             return type.toString();
4881         }
4882 
4883     }
4884     // </editor-fold>
4885 
4886     // <editor-fold defaultstate="collapsed" desc="Visitors">
4887     /**
4888      * A default visitor for types.  All visitor methods except
4889      * visitType are implemented by delegating to visitType.  Concrete
4890      * subclasses must provide an implementation of visitType and can
4891      * override other methods as needed.
4892      *
4893      * @param <R> the return type of the operation implemented by this
4894      * visitor; use Void if no return type is needed.
4895      * @param <S> the type of the second argument (the first being the
4896      * type itself) of the operation implemented by this visitor; use
4897      * Void if a second argument is not needed.
4898      */

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.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  *

  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 allowDefaultMethods;
  95     final boolean mapCapturesToBounds;
  96     final boolean allowValueBasedClasses;
  97     final Check chk;
  98     final Enter enter;
  99     JCDiagnostic.Factory diags;
 100     List<Warner> warnStack = List.nil();
 101     final Name capturedName;
 102 
 103     public final Warner noWarnings;
 104 
 105     // <editor-fold defaultstate="collapsed" desc="Instantiating">
 106     public static Types instance(Context context) {
 107         Types instance = context.get(typesKey);
 108         if (instance == null)
 109             instance = new Types(context);
 110         return instance;
 111     }
 112 
 113     protected Types(Context context) {
 114         context.put(typesKey, this);
 115         syms = Symtab.instance(context);
 116         names = Names.instance(context);
 117         Source source = Source.instance(context);
 118         allowDefaultMethods = Feature.DEFAULT_METHODS.allowedInSource(source);
 119         mapCapturesToBounds = Feature.MAP_CAPTURES_TO_BOUNDS.allowedInSource(source);
 120         chk = Check.instance(context);
 121         enter = Enter.instance(context);
 122         capturedName = names.fromString("<captured wildcard>");
 123         messages = JavacMessages.instance(context);
 124         diags = JCDiagnostic.Factory.instance(context);
 125         noWarnings = new Warner(null);
 126         Options options = Options.instance(context);
 127         allowValueBasedClasses = options.isSet("allowValueBasedClasses");
 128     }
 129     // </editor-fold>
 130 
 131     // <editor-fold defaultstate="collapsed" desc="bounds">
 132     /**
 133      * Get a wildcard's upper bound, returning non-wildcards unchanged.
 134      * @param t a type argument, either a wildcard or a type
 135      */
 136     public Type wildUpperBound(Type t) {
 137         if (t.hasTag(WILDCARD)) {
 138             WildcardType w = (WildcardType) t;
 139             if (w.isSuperBound())
 140                 return w.bound == null ? syms.objectType : w.bound.getUpperBound();
 141             else
 142                 return wildUpperBound(w.type);
 143         }
 144         else return t;
 145     }
 146 
 147     /**

 256                 if (components == components1) return t;
 257                 else return makeIntersectionType(components1);
 258             } else {
 259                 Type outer = t.getEnclosingType();
 260                 Type outer1 = visit(outer, pkind);
 261                 List<Type> typarams = t.getTypeArguments();
 262                 List<Type> formals = t.tsym.type.getTypeArguments();
 263                 ListBuffer<Type> typarams1 = new ListBuffer<>();
 264                 boolean changed = false;
 265                 for (Type actual : typarams) {
 266                     Type t2 = mapTypeArgument(t, formals.head.getUpperBound(), actual, pkind);
 267                     if (t2.hasTag(BOT)) {
 268                         //not defined
 269                         return syms.botType;
 270                     }
 271                     typarams1.add(t2);
 272                     changed |= actual != t2;
 273                     formals = formals.tail;
 274                 }
 275                 if (outer1 == outer && !changed) return t;
 276                 else return new ClassType(outer1, typarams1.toList(), t.tsym, t.getMetadata(), t.getFlavor()) {
 277                     @Override
 278                     protected boolean needsStripping() {
 279                         return true;
 280                     }
 281                 };
 282             }
 283         }
 284 
 285         @Override
 286         public Type visitArrayType(ArrayType t, ProjectionKind s) {
 287             Type elemtype = t.elemtype;
 288             Type elemtype1 = visit(elemtype, s);
 289             if (elemtype1 == elemtype) {
 290                 return t;
 291             } else if (elemtype1.hasTag(BOT)) {
 292                 //undefined
 293                 return syms.botType;
 294             } else {
 295                 return new ArrayType(elemtype1, t.tsym, t.metadata) {
 296                     @Override

 587                 }
 588                 return res;
 589             }
 590 
 591             @Override
 592             public Type visitErrorType(ErrorType t, Symbol sym) {
 593                 return t;
 594             }
 595         };
 596     // </editor-fold>
 597 
 598     // <editor-fold defaultstate="collapsed" desc="isConvertible">
 599     /**
 600      * Is t a subtype of or convertible via boxing/unboxing
 601      * conversion to s?
 602      */
 603     public boolean isConvertible(Type t, Type s, Warner warn) {
 604         if (t.hasTag(ERROR)) {
 605             return true;
 606         }
 607 
 608         boolean tValue = t.isPrimitiveClass();
 609         boolean sValue = s.isPrimitiveClass();
 610         if (tValue != sValue) {
 611             return tValue ?
 612                     isSubtype(t.referenceProjection(), s) :
 613                     !t.hasTag(BOT) && isSubtype(t, s.referenceProjection());
 614         }
 615 
 616         boolean tPrimitive = t.isPrimitive();
 617         boolean sPrimitive = s.isPrimitive();
 618         if (tPrimitive == sPrimitive) {
 619             return isSubtypeUnchecked(t, s, warn);
 620         }
 621         boolean tUndet = t.hasTag(UNDETVAR);
 622         boolean sUndet = s.hasTag(UNDETVAR);
 623 
 624         if (tUndet || sUndet) {
 625             return tUndet ?
 626                     isSubtype(t, boxedTypeOrType(s)) :
 627                     isSubtype(boxedTypeOrType(t), s);
 628         }
 629 
 630         return tPrimitive
 631             ? isSubtype(boxedClass(t).type, s)
 632             : isSubtype(unboxedType(t), s);
 633     }
 634 
 635     /**

 752                 Type mtype = memberType(origin.type, sym);
 753                 if (abstracts.isEmpty()) {
 754                     abstracts.append(sym);
 755                 } else if ((sym.name == abstracts.first().name &&
 756                         overrideEquivalent(mtype, memberType(origin.type, abstracts.first())))) {
 757                     if (!abstracts.stream().filter(msym -> msym.owner.isSubClass(sym.enclClass(), Types.this))
 758                             .map(msym -> memberType(origin.type, msym))
 759                             .anyMatch(abstractMType -> isSubSignature(abstractMType, mtype))) {
 760                         abstracts.append(sym);
 761                     }
 762                 } else {
 763                     //the target method(s) should be the only abstract members of t
 764                     throw failure("not.a.functional.intf.1",  origin,
 765                             diags.fragment(Fragments.IncompatibleAbstracts(Kinds.kindName(origin), origin)));
 766                 }
 767             }
 768             if (abstracts.isEmpty()) {
 769                 //t must define a suitable non-generic method
 770                 throw failure("not.a.functional.intf.1", origin,
 771                             diags.fragment(Fragments.NoAbstracts(Kinds.kindName(origin), origin)));
 772             }
 773             FunctionDescriptor descRes;
 774             if (abstracts.size() == 1) {
 775                 descRes = new FunctionDescriptor(abstracts.first());
 776             } else { // size > 1
 777                 descRes = mergeDescriptors(origin, abstracts.toList());
 778                 if (descRes == null) {
 779                     //we can get here if the functional interface is ill-formed
 780                     ListBuffer<JCDiagnostic> descriptors = new ListBuffer<>();
 781                     for (Symbol desc : abstracts) {
 782                         String key = desc.type.getThrownTypes().nonEmpty() ?
 783                                 "descriptor.throws" : "descriptor";
 784                         descriptors.append(diags.fragment(key, desc.name,
 785                                 desc.type.getParameterTypes(),
 786                                 desc.type.getReturnType(),
 787                                 desc.type.getThrownTypes()));
 788                     }
 789                     JCDiagnostic msg =
 790                             diags.fragment(Fragments.IncompatibleDescsInFunctionalIntf(Kinds.kindName(origin),
 791                                                                                        origin));
 792                     JCDiagnostic.MultilineDiagnostic incompatibleDescriptors =
 793                             new JCDiagnostic.MultilineDiagnostic(msg, descriptors.toList());
 794                     throw failure(incompatibleDescriptors);
 795                 }

 796             }
 797             // an interface must be neither an identity interface nor a value interface to be functional.
 798             List<Type> allInterfaces = closure(origin.type);
 799             for (Type iface : allInterfaces) {
 800                 if (iface.isValueInterface()) {
 801                     throw failure("not.a.functional.intf.1", origin, diags.fragment(Fragments.ValueInterfaceNonfunctional));
 802                 }
 803                 if (iface.isIdentityInterface()) {
 804                     throw failure("not.a.functional.intf.1", origin, diags.fragment(Fragments.IdentityInterfaceNonfunctional));
 805                 }
 806             }
 807             return descRes;
 808         }
 809 
 810         /**
 811          * Compute a synthetic type for the target descriptor given a list
 812          * of override-equivalent methods in the functional interface type.
 813          * The resulting method type is a method type that is override-equivalent
 814          * and return-type substitutable with each method in the original list.
 815          */
 816         private FunctionDescriptor mergeDescriptors(TypeSymbol origin, List<Symbol> methodSyms) {
 817             return mergeAbstracts(methodSyms, origin.type, false)
 818                     .map(bestSoFar -> new FunctionDescriptor(bestSoFar.baseSymbol()) {
 819                         @Override
 820                         public Type getType(Type origin) {
 821                             Type mt = memberType(origin, getSymbol());
 822                             return createMethodTypeWithThrown(mt, bestSoFar.type.getThrownTypes());
 823                         }
 824                     }).orElse(null);
 825         }
 826 
 827         FunctionDescriptorLookupError failure(String msg, Object... args) {

1027      */
1028     public boolean isSubtypeUnchecked(Type t, Type s) {
1029         return isSubtypeUnchecked(t, s, noWarnings);
1030     }
1031     /**
1032      * Is t an unchecked subtype of s?
1033      */
1034     public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) {
1035         boolean result = isSubtypeUncheckedInternal(t, s, true, warn);
1036         if (result) {
1037             checkUnsafeVarargsConversion(t, s, warn);
1038         }
1039         return result;
1040     }
1041     //where
1042         private boolean isSubtypeUncheckedInternal(Type t, Type s, boolean capture, Warner warn) {
1043             if (t.hasTag(ARRAY) && s.hasTag(ARRAY)) {
1044                 if (((ArrayType)t).elemtype.isPrimitive()) {
1045                     return isSameType(elemtype(t), elemtype(s));
1046                 } else {
1047                     // if T.ref <: S, then T[] <: S[]
1048                     Type es = elemtype(s);
1049                     Type et = elemtype(t);
1050                     if (et.isPrimitiveClass()) {
1051                         et = et.referenceProjection();
1052                         if (es.isPrimitiveClass())
1053                             es = es.referenceProjection();  // V <: V, surely
1054                     }
1055                     if (!isSubtypeUncheckedInternal(et, es, false, warn))
1056                         return false;
1057                     return true;
1058                 }
1059             } else if (isSubtype(t, s, capture)) {
1060                 return true;
1061             } else if (t.hasTag(TYPEVAR)) {
1062                 return isSubtypeUncheckedInternal(t.getUpperBound(), s, false, warn);
1063             } else if (!s.isRaw()) {
1064                 Type t2 = asSuper(t, s.tsym);
1065                 if (t2 != null && t2.isRaw()) {
1066                     if (isReifiable(s)) {
1067                         warn.silentWarn(LintCategory.UNCHECKED);
1068                     } else {
1069                         warn.warn(LintCategory.UNCHECKED);
1070                     }
1071                     return true;
1072                 }
1073             }
1074             return false;
1075         }
1076 
1077         private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) {

1134     }
1135     // where
1136         private TypeRelation isSubtype = new TypeRelation()
1137         {
1138             @Override
1139             public Boolean visitType(Type t, Type s) {
1140                 switch (t.getTag()) {
1141                  case BYTE:
1142                      return (!s.hasTag(CHAR) && t.getTag().isSubRangeOf(s.getTag()));
1143                  case CHAR:
1144                      return (!s.hasTag(SHORT) && t.getTag().isSubRangeOf(s.getTag()));
1145                  case SHORT: case INT: case LONG:
1146                  case FLOAT: case DOUBLE:
1147                      return t.getTag().isSubRangeOf(s.getTag());
1148                  case BOOLEAN: case VOID:
1149                      return t.hasTag(s.getTag());
1150                  case TYPEVAR:
1151                      return isSubtypeNoCapture(t.getUpperBound(), s);
1152                  case BOT:
1153                      return
1154                          s.hasTag(BOT) || (s.hasTag(CLASS) && !s.isPrimitiveClass()) ||
1155                          s.hasTag(ARRAY) || s.hasTag(TYPEVAR);
1156                  case WILDCARD: //we shouldn't be here - avoids crash (see 7034495)
1157                  case NONE:
1158                      return false;
1159                  default:
1160                      throw new AssertionError("isSubtype " + t.getTag());
1161                  }
1162             }
1163 
1164             private Set<TypePair> cache = new HashSet<>();
1165 
1166             private boolean containsTypeRecursive(Type t, Type s) {
1167                 TypePair pair = new TypePair(t, s);
1168                 if (cache.add(pair)) {
1169                     try {
1170                         return containsType(t.getTypeArguments(),
1171                                             s.getTypeArguments());
1172                     } finally {
1173                         cache.remove(pair);
1174                     }

1201                                              BoundKind.EXTENDS,
1202                                              syms.boundClass,
1203                                              s.getMetadata());
1204                         changed = true;
1205                     }
1206                     rewrite.append(s);
1207                 }
1208                 if (changed)
1209                     return subst(t.tsym.type, from.toList(), rewrite.toList());
1210                 else
1211                     return t;
1212             }
1213 
1214             @Override
1215             public Boolean visitClassType(ClassType t, Type s) {
1216                 Type sup = asSuper(t, s.tsym);
1217                 if (sup == null) return false;
1218                 // If t is an intersection, sup might not be a class type
1219                 if (!sup.hasTag(CLASS)) return isSubtypeNoCapture(sup, s);
1220                 return sup.tsym == s.tsym
1221                     && (t.tsym != s.tsym || t.isReferenceProjection() == s.isReferenceProjection())
1222                      // Check type variable containment
1223                     && (!s.isParameterized() || containsTypeRecursive(s, sup))
1224                     && isSubtypeNoCapture(sup.getEnclosingType(),
1225                                           s.getEnclosingType());
1226             }
1227 
1228             @Override
1229             public Boolean visitArrayType(ArrayType t, Type s) {
1230                 if (s.hasTag(ARRAY)) {
1231                     if (t.elemtype.isPrimitive())
1232                         return isSameType(t.elemtype, elemtype(s));
1233                     else {
1234                         // if T.ref <: S, then T[] <: S[]
1235                         Type es = elemtype(s);
1236                         Type et = elemtype(t);
1237                         if (et.isPrimitiveClass()) {
1238                             et = et.referenceProjection();
1239                             if (es.isPrimitiveClass())
1240                                 es = es.referenceProjection();  // V <: V, surely
1241                         }
1242                         return isSubtypeNoCapture(et, es);
1243                     }
1244                 }
1245 
1246                 if (s.hasTag(CLASS)) {
1247                     Name sname = s.tsym.getQualifiedName();
1248                     return sname == names.java_lang_Object
1249                         || sname == names.java_lang_Cloneable
1250                         || sname == names.java_io_Serializable;
1251                 }
1252 
1253                 return false;
1254             }
1255 
1256             @Override
1257             public Boolean visitUndetVar(UndetVar t, Type s) {
1258                 //todo: test against origin needed? or replace with substitution?
1259                 if (t == s || t.qtype == s || s.hasTag(ERROR) || s.hasTag(UNKNOWN)) {
1260                     return true;
1261                 } else if (s.hasTag(BOT)) {
1262                     //if 's' is 'null' there's no instantiated type U for which
1263                     //U <: s (but 'null' itself, which is not a valid type)

1446                     if (!visit(supertype(t), supertype(s)))
1447                         return false;
1448 
1449                     Map<Symbol,Type> tMap = new HashMap<>();
1450                     for (Type ti : interfaces(t)) {
1451                         if (tMap.containsKey(ti)) {
1452                             throw new AssertionError("Malformed intersection");
1453                         }
1454                         tMap.put(ti.tsym, ti);
1455                     }
1456                     for (Type si : interfaces(s)) {
1457                         if (!tMap.containsKey(si.tsym))
1458                             return false;
1459                         Type ti = tMap.remove(si.tsym);
1460                         if (!visit(ti, si))
1461                             return false;
1462                     }
1463                     return tMap.isEmpty();
1464                 }
1465                 return t.tsym == s.tsym
1466                     && t.isReferenceProjection() == s.isReferenceProjection()
1467                     && visit(getEnclosingType(t), getEnclosingType(s))
1468                     && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments());
1469             }
1470                 // where
1471                 private Type getEnclosingType(Type t) {
1472                     Type et = t.getEnclosingType();
1473                     if (et.isReferenceProjection()) {
1474                         et = et.valueProjection();
1475                     }
1476                     return et;
1477                 }
1478 
1479             @Override
1480             public Boolean visitArrayType(ArrayType t, Type s) {
1481                 if (t == s)
1482                     return true;
1483 
1484                 if (s.isPartial())
1485                     return visit(s, t);
1486 
1487                 return s.hasTag(ARRAY)
1488                     && containsTypeEquivalent(t.elemtype, elemtype(s));
1489             }
1490 
1491             @Override
1492             public Boolean visitMethodType(MethodType t, Type s) {
1493                 // isSameType for methods does not take thrown
1494                 // exceptions into account!
1495                 return hasSameArgs(t, s) && visit(t.getReturnType(), s.getReturnType());
1496             }
1497 

1617 //            void debugContainsType(WildcardType t, Type s) {
1618 //                System.err.println();
1619 //                System.err.format(" does %s contain %s?%n", t, s);
1620 //                System.err.format(" %s U(%s) <: U(%s) %s = %s%n",
1621 //                                  wildUpperBound(s), s, t, wildUpperBound(t),
1622 //                                  t.isSuperBound()
1623 //                                  || isSubtypeNoCapture(wildUpperBound(s), wildUpperBound(t)));
1624 //                System.err.format(" %s L(%s) <: L(%s) %s = %s%n",
1625 //                                  wildLowerBound(t), t, s, wildLowerBound(s),
1626 //                                  t.isExtendsBound()
1627 //                                  || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s)));
1628 //                System.err.println();
1629 //            }
1630 
1631             @Override
1632             public Boolean visitWildcardType(WildcardType t, Type s) {
1633                 if (s.isPartial())
1634                     return containedBy(s, t);
1635                 else {
1636 //                    debugContainsType(t, s);
1637 
1638                     // -----------------------------------  Unspecified behavior ----------------
1639 
1640                     /* If a primitive class V implements an interface I, then does "? extends I" contain V?
1641                        It seems widening must be applied here to answer yes to compile some common code
1642                        patterns.
1643                     */
1644 
1645                     // ---------------------------------------------------------------------------
1646                     return isSameWildcard(t, s)
1647                         || isCaptureOf(s, t)
1648                         || ((t.isExtendsBound() || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s))) &&
1649                             (t.isSuperBound() || isSubtypeNoCapture(wildUpperBound(s), wildUpperBound(t))));
1650                 }
1651             }
1652 
1653             @Override
1654             public Boolean visitUndetVar(UndetVar t, Type s) {
1655                 if (!s.hasTag(WILDCARD)) {
1656                     return isSameType(t, s);
1657                 } else {
1658                     return false;
1659                 }
1660             }
1661 
1662             @Override
1663             public Boolean visitErrorType(ErrorType t, Type s) {
1664                 return true;
1665             }

1715                 warnStack = warnStack.prepend(warn);
1716                 checkUnsafeVarargsConversion(t, s, warn);
1717                 result = isCastable.visit(t,s);
1718             } finally {
1719                 warnStack = warnStack.tail;
1720             }
1721         } else {
1722             result = isCastable.visit(t,s);
1723         }
1724         if (result && t.hasTag(CLASS) && t.tsym.kind.matches(Kinds.KindSelector.TYP)
1725                 && s.hasTag(CLASS) && s.tsym.kind.matches(Kinds.KindSelector.TYP)
1726                 && (t.tsym.isSealed() || s.tsym.isSealed())) {
1727             return (t.isCompound() || s.isCompound()) ?
1728                     true :
1729                     !areDisjoint((ClassSymbol)t.tsym, (ClassSymbol)s.tsym);
1730         }
1731         return result;
1732     }
1733     // where
1734         private boolean areDisjoint(ClassSymbol ts, ClassSymbol ss) {
1735             if (isSubtype(erasure(ts.type.referenceProjectionOrSelf()), erasure(ss.type))) {
1736                 return false;
1737             }
1738             // if both are classes or both are interfaces, shortcut
1739             if (ts.isInterface() == ss.isInterface() && isSubtype(erasure(ss.type), erasure(ts.type))) {
1740                 return false;
1741             }
1742             if (ts.isInterface() && !ss.isInterface()) {
1743                 /* so ts is interface but ss is a class
1744                  * an interface is disjoint from a class if the class is disjoint form the interface
1745                  */
1746                 return areDisjoint(ss, ts);
1747             }
1748             // a final class that is not subtype of ss is disjoint
1749             if (!ts.isInterface() && ts.isFinal()) {
1750                 return true;
1751             }
1752             // if at least one is sealed
1753             if (ts.isSealed() || ss.isSealed()) {
1754                 // permitted subtypes have to be disjoint with the other symbol
1755                 ClassSymbol sealedOne = ts.isSealed() ? ts : ss;

1770                 case DOUBLE:
1771                     return s.isNumeric();
1772                 case BOOLEAN:
1773                     return s.hasTag(BOOLEAN);
1774                 case VOID:
1775                     return false;
1776                 case BOT:
1777                     return isSubtype(t, s);
1778                 default:
1779                     throw new AssertionError();
1780                 }
1781             }
1782 
1783             @Override
1784             public Boolean visitWildcardType(WildcardType t, Type s) {
1785                 return isCastable(wildUpperBound(t), s, warnStack.head);
1786             }
1787 
1788             @Override
1789             public Boolean visitClassType(ClassType t, Type s) {
1790                 if (s.hasTag(ERROR) || (s.hasTag(BOT) && !t.isPrimitiveClass()))
1791                     return true;
1792 
1793                 if (s.hasTag(TYPEVAR)) {
1794                     if (isCastable(t, s.getUpperBound(), noWarnings)) {
1795                         warnStack.head.warn(LintCategory.UNCHECKED);
1796                         return true;
1797                     } else {
1798                         return false;
1799                     }
1800                 }
1801 
1802                 if (t.isCompound() || s.isCompound()) {
1803                     return !t.isCompound() ?
1804                             visitCompoundType((ClassType)s, t, true) :
1805                             visitCompoundType(t, s, false);
1806                 }
1807 
1808                 if (s.hasTag(CLASS) || s.hasTag(ARRAY)) {
1809                     if (t.isPrimitiveClass()) {
1810                         // (s) Value ? == (s) Value.ref
1811                         t = t.referenceProjection();
1812                     }
1813                     if (s.isPrimitiveClass()) {
1814                         // (Value) t ? == (Value.ref) t
1815                         s = s.referenceProjection();
1816                     }
1817                     boolean upcast;
1818                     if ((upcast = isSubtype(erasure(t), erasure(s)))
1819                         || isSubtype(erasure(s), erasure(t))) {
1820                         if (!upcast && s.hasTag(ARRAY)) {
1821                             if (!isReifiable(s))
1822                                 warnStack.head.warn(LintCategory.UNCHECKED);
1823                             return true;
1824                         } else if (s.isRaw()) {
1825                             return true;
1826                         } else if (t.isRaw()) {
1827                             if (!isUnbounded(s))
1828                                 warnStack.head.warn(LintCategory.UNCHECKED);
1829                             return true;
1830                         }
1831                         // Assume |a| <: |b|
1832                         final Type a = upcast ? t : s;
1833                         final Type b = upcast ? s : t;
1834                         final boolean HIGH = true;
1835                         final boolean LOW = false;
1836                         final boolean DONT_REWRITE_TYPEVARS = false;

1902 
1903             @Override
1904             public Boolean visitArrayType(ArrayType t, Type s) {
1905                 switch (s.getTag()) {
1906                 case ERROR:
1907                 case BOT:
1908                     return true;
1909                 case TYPEVAR:
1910                     if (isCastable(s, t, noWarnings)) {
1911                         warnStack.head.warn(LintCategory.UNCHECKED);
1912                         return true;
1913                     } else {
1914                         return false;
1915                     }
1916                 case CLASS:
1917                     return isSubtype(t, s);
1918                 case ARRAY:
1919                     if (elemtype(t).isPrimitive() || elemtype(s).isPrimitive()) {
1920                         return elemtype(t).hasTag(elemtype(s).getTag());
1921                     } else {
1922                         Type et = elemtype(t);
1923                         Type es = elemtype(s);
1924                         if (!visit(et, es))
1925                             return false;
1926                         return true;
1927                     }
1928                 default:
1929                     return false;
1930                 }
1931             }
1932 
1933             @Override
1934             public Boolean visitTypeVar(TypeVar t, Type s) {
1935                 switch (s.getTag()) {
1936                 case ERROR:
1937                 case BOT:
1938                     return true;
1939                 case TYPEVAR:
1940                     if (isSubtype(t, s)) {
1941                         return true;
1942                     } else if (isCastable(t.getUpperBound(), s, noWarnings)) {
1943                         warnStack.head.warn(LintCategory.UNCHECKED);
1944                         return true;
1945                     } else {
1946                         return false;

2194      * @return the ArrayType for the given component
2195      */
2196     public ArrayType makeArrayType(Type t) {
2197         if (t.hasTag(VOID) || t.hasTag(PACKAGE)) {
2198             Assert.error("Type t must not be a VOID or PACKAGE type, " + t.toString());
2199         }
2200         return new ArrayType(t, syms.arrayClass);
2201     }
2202     // </editor-fold>
2203 
2204     // <editor-fold defaultstate="collapsed" desc="asSuper">
2205     /**
2206      * Return the (most specific) base type of t that starts with the
2207      * given symbol.  If none exists, return null.
2208      *
2209      * Caveat Emptor: Since javac represents the class of all arrays with a singleton
2210      * symbol Symtab.arrayClass, which by being a singleton cannot hold any discriminant,
2211      * this method could yield surprising answers when invoked on arrays. For example when
2212      * invoked with t being byte [] and sym being t.sym itself, asSuper would answer null.
2213      *
2214      * Further caveats in Valhalla: There are two "hazards" we need to watch out for when using
2215      * this method.
2216      *
2217      * 1. Since Foo.ref and Foo.val share the same symbol, that of Foo.class, a call to
2218      *    asSuper(Foo.ref.type, Foo.val.type.tsym) would return non-null. This MAY NOT BE correct
2219      *    depending on the call site. Foo.val is NOT a super type of Foo.ref either in the language
2220      *    model or in the VM's world view. An example of such an hazardous call used to exist in
2221      *    Gen.visitTypeCast. When we emit code for  (Foo) Foo.ref.instance a check for whether we
2222      *    really need the cast cannot/shouldn't be gated on
2223      *
2224      *        asSuper(tree.expr.type, tree.clazz.type.tsym) == null)
2225      *
2226      *    but use !types.isSubtype(tree.expr.type, tree.clazz.type) which operates in terms of
2227      *    types. When we operate in terms of symbols, there is a loss of type information leading
2228      *    to a hazard. Whether a call to asSuper should be transformed into a isSubtype call is
2229      *    tricky. isSubtype returns just a boolean while asSuper returns richer information which
2230      *    may be required at the call site. Also where the concerned symbol corresponds to a
2231      *    generic class, an asSuper call cannot be conveniently rewritten as an isSubtype call
2232      *    (see that asSuper(ArrayList<String>.type, List<T>.tsym) != null while
2233      *    isSubType(ArrayList<String>.type, List<T>.type) is false;) So care needs to be exercised.
2234      *
2235      * 2. Given a primitive class Foo, a call to asSuper(Foo.type, SuperclassOfFoo.tsym) and/or
2236      *    a call to asSuper(Foo.type, SuperinterfaceOfFoo.tsym) would answer null. In many places
2237      *    that is NOT what we want. An example of such a hazardous call used to occur in
2238      *    Attr.visitForeachLoop when checking to make sure the for loop's control variable of a type
2239      *    that implements Iterable: viz: types.asSuper(exprType, syms.iterableType.tsym);
2240      *    These hazardous calls should be rewritten as
2241      *    types.asSuper(exprType.referenceProjectionOrSelf(), syms.iterableType.tsym); instead.
2242      *
2243      * @param t a type
2244      * @param sym a symbol
2245      */
2246     public Type asSuper(Type t, Symbol sym) {
2247         /* Some examples:
2248          *
2249          * (Enum<E>, Comparable) => Comparable<E>
2250          * (c.s.s.d.AttributeTree.ValueKind, Enum) => Enum<c.s.s.d.AttributeTree.ValueKind>
2251          * (c.s.s.t.ExpressionTree, c.s.s.t.Tree) => c.s.s.t.Tree
2252          * (j.u.List<capture#160 of ? extends c.s.s.d.DocTree>, Iterable) =>
2253          *     Iterable<capture#160 of ? extends c.s.s.d.DocTree>
2254          */
2255 
2256         if (t.isPrimitiveClass()) {
2257             // No man may be an island, but the bell tolls for a value.
2258             return t.tsym == sym ? t : null;
2259         }
2260 
2261         if (sym.type == syms.objectType) { //optimization
2262             return syms.objectType;
2263         }
2264         return asSuper.visit(t, sym);
2265     }
2266     // where
2267         private SimpleVisitor<Type,Symbol> asSuper = new SimpleVisitor<Type,Symbol>() {
2268 
2269             private Set<Symbol> seenTypes = new HashSet<>();
2270 
2271             public Type visitType(Type t, Symbol sym) {
2272                 return null;
2273             }
2274 
2275             @Override
2276             public Type visitClassType(ClassType t, Symbol sym) {
2277                 if (t.tsym == sym)
2278                     return t;
2279 
2280                 Symbol c = t.tsym;

2305 
2306             @Override
2307             public Type visitArrayType(ArrayType t, Symbol sym) {
2308                 return isSubtype(t, sym.type) ? sym.type : null;
2309             }
2310 
2311             @Override
2312             public Type visitTypeVar(TypeVar t, Symbol sym) {
2313                 if (t.tsym == sym)
2314                     return t;
2315                 else
2316                     return asSuper(t.getUpperBound(), sym);
2317             }
2318 
2319             @Override
2320             public Type visitErrorType(ErrorType t, Symbol sym) {
2321                 return t;
2322             }
2323         };
2324 
2325     public boolean isIdentityType(Type t) {
2326         if (t.isPrimitiveClass() || t.isReferenceProjection() || t.isValueClass() || t.isValueInterface()) {
2327             return false;
2328         }
2329         if (t.tsym == syms.objectType.tsym) {
2330             return false;
2331         }
2332         if (t.hasTag(ARRAY))
2333             return true;
2334         if (t.hasTag(CLASS) && !t.isValueClass() && !t.isReferenceProjection() && !t.tsym.isInterface() && !t.tsym.isAbstract()) {
2335             return true;
2336         }
2337         if (implicitIdentityType(t)) {
2338             return true;
2339         }
2340         return false;
2341     }
2342         // where
2343         private boolean implicitIdentityType(Type t) {
2344             /* An abstract class can be declared with the identity/value modifier;
2345              * or, if it declares a field, an instance initializer, a non-empty constructor, or
2346              * a synchronized instance method, it implicitly is an Identity type.
2347              */
2348             if (!t.tsym.isAbstract())
2349                 return false;
2350 
2351             for (; t != Type.noType; t = supertype(t)) {
2352 
2353                 if (t == null || t.tsym == null || t.tsym.kind == ERR)
2354                     return false;
2355 
2356                 if  (t.tsym == syms.objectType.tsym)
2357                     return false;
2358 
2359                 if (!t.tsym.isAbstract()) {
2360                     return !t.tsym.isPrimitiveClass();
2361                 }
2362 
2363                 if ((t.tsym.flags() & HASINITBLOCK) != 0) {
2364                     return true;
2365                 }
2366 
2367                 // No instance fields and no arged constructors both mean inner classes cannot be primitive class supers.
2368                 Type encl = t.getEnclosingType();
2369                 if (encl != null && encl.hasTag(CLASS)) {
2370                     return true;
2371                 }
2372                 for (Symbol s : t.tsym.members().getSymbols(NON_RECURSIVE)) {
2373                     switch (s.kind) {
2374                         case VAR:
2375                             if ((s.flags() & STATIC) == 0) {
2376                                 return true;
2377                             }
2378                             break;
2379                         case MTH:
2380                             if ((s.flags() & (SYNCHRONIZED | STATIC)) == SYNCHRONIZED) {
2381                                 return true;
2382                             } else if (s.isConstructor()) {
2383                                 MethodSymbol m = (MethodSymbol)s;
2384                                 if (m.getParameters().size() > 0 || (m.flags() & EMPTYNOARGCONSTR) == 0) {
2385                                     return true;
2386                                 }
2387                             }
2388                             break;
2389                     }
2390                 }
2391             }
2392             return false;
2393         }
2394 
2395     /**
2396      * Return the base type of t or any of its outer types that starts
2397      * with the given symbol.  If none exists, return null.
2398      *
2399      * @param t a type
2400      * @param sym a symbol
2401      */
2402     public Type asOuterSuper(Type t, Symbol sym) {
2403         switch (t.getTag()) {
2404         case CLASS:
2405             do {
2406                 Type s = asSuper(t, sym);
2407                 if (s != null) return s;
2408                 t = t.getEnclosingType();
2409             } while (t.hasTag(CLASS));
2410             return null;
2411         case ARRAY:
2412             return isSubtype(t, sym.type) ? sym.type : null;
2413         case TYPEVAR:
2414             return asSuper(t, sym);

2441         case ARRAY:
2442             return isSubtype(t, sym.type) ? sym.type : null;
2443         case TYPEVAR:
2444             return asSuper(t, sym);
2445         case ERROR:
2446             return t;
2447         default:
2448             return null;
2449         }
2450     }
2451     // </editor-fold>
2452 
2453     // <editor-fold defaultstate="collapsed" desc="memberType">
2454     /**
2455      * The type of given symbol, seen as a member of t.
2456      *
2457      * @param t a type
2458      * @param sym a symbol
2459      */
2460     public Type memberType(Type t, Symbol sym) {
2461 
2462         if ((sym.flags() & STATIC) != 0)
2463             return sym.type;
2464 
2465         /* If any primitive class types are involved, switch over to the reference universe,
2466            where the hierarchy is navigable. V and V.ref have identical membership
2467            with no bridging needs.
2468         */
2469         if (t.isPrimitiveClass())
2470             t = t.referenceProjection();
2471 
2472         return memberType.visit(t, sym);
2473         }
2474     // where
2475         private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
2476 
2477             public Type visitType(Type t, Symbol sym) {
2478                 return sym.type;
2479             }
2480 
2481             @Override
2482             public Type visitWildcardType(WildcardType t, Symbol sym) {
2483                 return memberType(wildUpperBound(t), sym);
2484             }
2485 
2486             @Override
2487             public Type visitClassType(ClassType t, Symbol sym) {
2488                 Symbol owner = sym.owner;
2489                 long flags = sym.flags();
2490                 if (((flags & STATIC) == 0) && owner.type.isParameterized()) {
2491                     Type base = asOuterSuper(t, owner);
2492                     //if t is an intersection type T = CT & I1 & I2 ... & In

2605                 }
2606             }
2607 
2608             public Type visitType(Type t, Boolean recurse) {
2609                 if (t.isPrimitive())
2610                     return t; /*fast special case*/
2611                 else {
2612                     //other cases already handled
2613                     return combineMetadata(t, t);
2614                 }
2615             }
2616 
2617             @Override
2618             public Type visitWildcardType(WildcardType t, Boolean recurse) {
2619                 Type erased = erasure(wildUpperBound(t), recurse);
2620                 return combineMetadata(erased, t);
2621             }
2622 
2623             @Override
2624             public Type visitClassType(ClassType t, Boolean recurse) {
2625                 // erasure(projection(primitive)) = projection(erasure(primitive))
2626                 Type erased = eraseClassType(t, recurse);
2627                 if (erased.hasTag(CLASS) && t.flavor != erased.getFlavor()) {
2628                     erased = new ClassType(erased.getEnclosingType(),
2629                             List.nil(), erased.tsym,
2630                             erased.getMetadata(), t.flavor);
2631                 }
2632                 return erased;
2633             }
2634                 // where
2635                 private Type eraseClassType(ClassType t, Boolean recurse) {
2636                     Type erased = t.tsym.erasure(Types.this);
2637                     if (recurse) {
2638                         erased = new ErasedClassType(erased.getEnclosingType(), erased.tsym,
2639                                 t.getMetadata().without(Kind.ANNOTATIONS));
2640                         return erased;
2641                     } else {
2642                         return combineMetadata(erased, t);
2643                     }
2644                 }

2645 
2646             @Override
2647             public Type visitTypeVar(TypeVar t, Boolean recurse) {
2648                 Type erased = erasure(t.getUpperBound(), recurse);
2649                 return combineMetadata(erased, t);
2650             }
2651         };
2652 
2653     public List<Type> erasure(List<Type> ts) {
2654         return erasure.visit(ts, false);
2655     }
2656 
2657     public Type erasureRecursive(Type t) {
2658         return erasure(t, true);
2659     }
2660 
2661     public List<Type> erasureRecursive(List<Type> ts) {
2662         return erasure.visit(ts, true);
2663     }
2664     // </editor-fold>

2673      */
2674     public IntersectionClassType makeIntersectionType(List<Type> bounds) {
2675         return makeIntersectionType(bounds, bounds.head.tsym.isInterface());
2676     }
2677 
2678     /**
2679      * Make an intersection type from non-empty list of types.  The list should be ordered according to
2680      * {@link TypeSymbol#precedes(TypeSymbol, Types)}. This does not cause symbol completion as
2681      * an extra parameter indicates as to whether all bounds are interfaces - in which case the
2682      * supertype is implicitly assumed to be 'Object'.
2683      *
2684      * @param bounds        the types from which the intersection type is formed
2685      * @param allInterfaces are all bounds interface types?
2686      */
2687     public IntersectionClassType makeIntersectionType(List<Type> bounds, boolean allInterfaces) {
2688         Assert.check(bounds.nonEmpty());
2689         Type firstExplicitBound = bounds.head;
2690         if (allInterfaces) {
2691             bounds = bounds.prepend(syms.objectType);
2692         }
2693         long flags = ABSTRACT | PUBLIC | SYNTHETIC | COMPOUND | ACYCLIC;
2694         ClassSymbol bc =
2695             new ClassSymbol(flags,
2696                             Type.moreInfo
2697                                 ? names.fromString(bounds.toString())
2698                                 : names.empty,
2699                             null,
2700                             syms.noSymbol);
2701         IntersectionClassType intersectionType = new IntersectionClassType(bounds, bc, allInterfaces);
2702         bc.type = intersectionType;
2703         bc.erasure_field = (bounds.head.hasTag(TYPEVAR)) ?
2704                 syms.objectType : // error condition, recover
2705                 erasure(firstExplicitBound);
2706         bc.members_field = WriteableScope.create(bc);
2707         return intersectionType;
2708     }
2709     // </editor-fold>
2710 
2711     // <editor-fold defaultstate="collapsed" desc="supertype">
2712     public Type supertype(Type t) {
2713         return supertype.visit(t);
2714     }
2715     // where

2945     /**
2946      * If the given type is a (possibly selected) type variable,
2947      * return the bounding class of this type, otherwise return the
2948      * type itself.
2949      */
2950     public Type classBound(Type t) {
2951         return classBound.visit(t);
2952     }
2953     // where
2954         private UnaryVisitor<Type> classBound = new UnaryVisitor<Type>() {
2955 
2956             public Type visitType(Type t, Void ignored) {
2957                 return t;
2958             }
2959 
2960             @Override
2961             public Type visitClassType(ClassType t, Void ignored) {
2962                 Type outer1 = classBound(t.getEnclosingType());
2963                 if (outer1 != t.getEnclosingType())
2964                     return new ClassType(outer1, t.getTypeArguments(), t.tsym,
2965                                          t.getMetadata(), t.getFlavor());
2966                 else
2967                     return t;
2968             }
2969 
2970             @Override
2971             public Type visitTypeVar(TypeVar t, Void ignored) {
2972                 return classBound(supertype(t));
2973             }
2974 
2975             @Override
2976             public Type visitErrorType(ErrorType t, Void ignored) {
2977                 return t;
2978             }
2979         };
2980     // </editor-fold>
2981 
2982     // <editor-fold defaultstate="collapsed" desc="sub signature / override equivalence">
2983     /**
2984      * Returns true iff the first signature is a <em>sub
2985      * signature</em> of the other.  This is <b>not</b> an equivalence

4072                         m = new WildcardType(lub(wildUpperBound(act1.head),
4073                                                  wildUpperBound(act2.head)),
4074                                              BoundKind.EXTENDS,
4075                                              syms.boundClass);
4076                         mergeCache.remove(pair);
4077                     } else {
4078                         m = new WildcardType(syms.objectType,
4079                                              BoundKind.UNBOUND,
4080                                              syms.boundClass);
4081                     }
4082                     merged.append(m.withTypeVar(typarams.head));
4083                 }
4084                 act1 = act1.tail;
4085                 act2 = act2.tail;
4086                 typarams = typarams.tail;
4087             }
4088             Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
4089             // There is no spec detailing how type annotations are to
4090             // be inherited.  So set it to noAnnotations for now
4091             return new ClassType(class1.getEnclosingType(), merged.toList(),
4092                                  class1.tsym, TypeMetadata.EMPTY, class1.getFlavor());
4093         }
4094 
4095     /**
4096      * Return the minimum type of a closure, a compound type if no
4097      * unique minimum exists.
4098      */
4099     private Type compoundMin(List<Type> cl) {
4100         if (cl.isEmpty()) return syms.objectType;
4101         List<Type> compound = closureMin(cl);
4102         if (compound.isEmpty())
4103             return null;
4104         else if (compound.tail.isEmpty())
4105             return compound.head;
4106         else
4107             return makeIntersectionType(compound);
4108     }
4109 
4110     /**
4111      * Return the minimum types of a closure, suitable for computing
4112      * compoundMin or glb.

4144     }
4145 
4146     /**
4147      * Return the least upper bound of list of types.  if the lub does
4148      * not exist return null.
4149      */
4150     public Type lub(List<Type> ts) {
4151         return lub(ts.toArray(new Type[ts.length()]));
4152     }
4153 
4154     /**
4155      * Return the least upper bound (lub) of set of types.  If the lub
4156      * does not exist return the type of null (bottom).
4157      */
4158     public Type lub(Type... ts) {
4159         final int UNKNOWN_BOUND = 0;
4160         final int ARRAY_BOUND = 1;
4161         final int CLASS_BOUND = 2;
4162 
4163         int[] kinds = new int[ts.length];

4164         int boundkind = UNKNOWN_BOUND;
4165         for (int i = 0 ; i < ts.length ; i++) {
4166             Type t = ts[i];
4167             switch (t.getTag()) {
4168             case CLASS:
4169                 boundkind |= kinds[i] = CLASS_BOUND;
4170                 break;
4171             case ARRAY:
4172                 boundkind |= kinds[i] = ARRAY_BOUND;
4173                 break;
4174             case  TYPEVAR:
4175                 do {
4176                     t = t.getUpperBound();
4177                 } while (t.hasTag(TYPEVAR));
4178                 if (t.hasTag(ARRAY)) {
4179                     boundkind |= kinds[i] = ARRAY_BOUND;
4180                 } else {
4181                     boundkind |= kinds[i] = CLASS_BOUND;
4182                 }
4183                 break;

4631                     Si.lower = Ti.getSuperBound();
4632                     break;
4633                 }
4634                 Type tmpBound = Si.getUpperBound().hasTag(UNDETVAR) ? ((UndetVar)Si.getUpperBound()).qtype : Si.getUpperBound();
4635                 Type tmpLower = Si.lower.hasTag(UNDETVAR) ? ((UndetVar)Si.lower).qtype : Si.lower;
4636                 if (!Si.getUpperBound().hasTag(ERROR) &&
4637                     !Si.lower.hasTag(ERROR) &&
4638                     isSameType(tmpBound, tmpLower)) {
4639                     currentS.head = Si.getUpperBound();
4640                 }
4641             }
4642             currentA = currentA.tail;
4643             currentT = currentT.tail;
4644             currentS = currentS.tail;
4645         }
4646         if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty())
4647             return erasure(t); // some "rare" type involved
4648 
4649         if (captured)
4650             return new ClassType(cls.getEnclosingType(), S, cls.tsym,
4651                                  cls.getMetadata(), cls.getFlavor());
4652         else
4653             return t;
4654     }
4655     // where
4656         public List<Type> freshTypeVariables(List<Type> types) {
4657             ListBuffer<Type> result = new ListBuffer<>();
4658             for (Type t : types) {
4659                 if (t.hasTag(WILDCARD)) {
4660                     Type bound = ((WildcardType)t).getExtendsBound();
4661                     if (bound == null)
4662                         bound = syms.objectType;
4663                     result.append(new CapturedType(capturedName,
4664                                                    syms.noSymbol,
4665                                                    bound,
4666                                                    syms.botType,
4667                                                    (WildcardType)t));
4668                 } else {
4669                     result.append(t);
4670                 }
4671             }

5042     private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
5043         if (bound.hasTag(BOT)) {
5044             return new WildcardType(syms.objectType,
5045                                     BoundKind.UNBOUND,
5046                                     syms.boundClass,
5047                                     formal);
5048         } else {
5049             return new WildcardType(bound,
5050                                     BoundKind.SUPER,
5051                                     syms.boundClass,
5052                                     formal);
5053         }
5054     }
5055 
5056     /**
5057      * A wrapper for a type that allows use in sets.
5058      */
5059     public static class UniqueType {
5060         public final Type type;
5061         final Types types;
5062         private boolean encodeTypeSig;
5063 
5064         public UniqueType(Type type, Types types, boolean encodeTypeSig) {
5065             this.type = type;
5066             this.types = types;
5067             this.encodeTypeSig = encodeTypeSig;
5068         }
5069 
5070         public UniqueType(Type type, Types types) {
5071             this(type, types, true);
5072         }
5073 
5074         public int hashCode() {
5075             return types.hashCode(type);
5076         }
5077 
5078         public boolean equals(Object obj) {
5079             return (obj instanceof UniqueType uniqueType) &&
5080                     types.isSameType(type, uniqueType.type);
5081         }
5082 
5083         public boolean encodeTypeSig() {
5084             return encodeTypeSig;
5085         }
5086 
5087         public String toString() {
5088             return type.toString();
5089         }
5090 
5091     }
5092     // </editor-fold>
5093 
5094     // <editor-fold defaultstate="collapsed" desc="Visitors">
5095     /**
5096      * A default visitor for types.  All visitor methods except
5097      * visitType are implemented by delegating to visitType.  Concrete
5098      * subclasses must provide an implementation of visitType and can
5099      * override other methods as needed.
5100      *
5101      * @param <R> the return type of the operation implemented by this
5102      * visitor; use Void if no return type is needed.
5103      * @param <S> the type of the second argument (the first being the
5104      * type itself) of the operation implemented by this visitor; use
5105      * Void if a second argument is not needed.
5106      */

5299                     break;
5300                 case LONG:
5301                     append('J');
5302                     break;
5303                 case FLOAT:
5304                     append('F');
5305                     break;
5306                 case DOUBLE:
5307                     append('D');
5308                     break;
5309                 case BOOLEAN:
5310                     append('Z');
5311                     break;
5312                 case VOID:
5313                     append('V');
5314                     break;
5315                 case CLASS:
5316                     if (type.isCompound()) {
5317                         reportIllegalSignature(type);
5318                     }
5319                     if (type.isPrimitiveClass())
5320                         append('Q');
5321                     else
5322                         append('L');
5323                     assembleClassSig(type);
5324                     append(';');
5325                     break;
5326                 case ARRAY:
5327                     ArrayType at = (ArrayType) type;
5328                     append('[');
5329                     assembleSig(at.elemtype);
5330                     break;
5331                 case METHOD:
5332                     MethodType mt = (MethodType) type;
5333                     append('(');
5334                     assembleSig(mt.argtypes);
5335                     append(')');
5336                     assembleSig(mt.restype);
5337                     if (hasTypeVar(mt.thrown)) {
5338                         for (List<Type> l = mt.thrown; l.nonEmpty(); l = l.tail) {
5339                             append('^');
5340                             assembleSig(l.head);
5341                         }
5342                     }
< prev index next >