< 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.Annotations;
  48 import com.sun.tools.javac.comp.AttrContext;
  49 import com.sun.tools.javac.comp.Check;
  50 import com.sun.tools.javac.comp.Enter;
  51 import com.sun.tools.javac.comp.Env;
  52 import com.sun.tools.javac.comp.LambdaToMethod;
  53 import com.sun.tools.javac.jvm.ClassFile;
  54 import com.sun.tools.javac.util.*;
  55 
  56 import static com.sun.tools.javac.code.BoundKind.*;
  57 import static com.sun.tools.javac.code.Flags.*;
  58 import static com.sun.tools.javac.code.Kinds.Kind.*;
  59 import static com.sun.tools.javac.code.Scope.*;
  60 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
  61 import static com.sun.tools.javac.code.Symbol.*;
  62 import static com.sun.tools.javac.code.Type.*;
  63 import static com.sun.tools.javac.code.TypeTag.*;
  64 import static com.sun.tools.javac.jvm.ClassFile.externalize;
  65 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  66 
  67 /**
  68  * Utility class containing various operations on types.
  69  *
  70  * <p>Unless other names are more illustrative, the following naming
  71  * conventions should be observed in this file:
  72  *

  75  * <dd>If the first argument to an operation is a type, it should be named t.</dd>
  76  * <dt>s</dt>
  77  * <dd>Similarly, if the second argument to an operation is a type, it should be named s.</dd>
  78  * <dt>ts</dt>
  79  * <dd>If an operations takes a list of types, the first should be named ts.</dd>
  80  * <dt>ss</dt>
  81  * <dd>A second list of types should be named ss.</dd>
  82  * </dl>
  83  *
  84  * <p><b>This is NOT part of any supported API.
  85  * If you write code that depends on this, you do so at your own risk.
  86  * This code and its internal interfaces are subject to change or
  87  * deletion without notice.</b>
  88  */
  89 public class Types {
  90     protected static final Context.Key<Types> typesKey = new Context.Key<>();
  91 
  92     final Symtab syms;
  93     final JavacMessages messages;
  94     final Names names;

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


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

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

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











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

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


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











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

 936             else if (descSym.overrides(m2, origin, Types.this, false)) {
 937                 for (Symbol m3 : overridden) {
 938                     if (isSameType(m3.erasure(Types.this), m2.erasure(Types.this)) ||
 939                             (m3.overrides(m2, origin, Types.this, false) &&
 940                             (pendingBridges((ClassSymbol)origin, m3.enclClass()) ||
 941                             (((MethodSymbol)m2).binaryImplementation((ClassSymbol)m3.owner, Types.this) != null)))) {
 942                         continue outer;
 943                     }
 944                 }
 945                 overridden.add(m2);
 946             }
 947         }
 948         return overridden.toList();
 949     }
 950     //where
 951         // Use anonymous class instead of lambda expression intentionally,
 952         // because the variable `names` has modifier: final.
 953         private Predicate<Symbol> bridgeFilter = new Predicate<Symbol>() {
 954             public boolean test(Symbol t) {
 955                 return t.kind == MTH &&
 956                         t.name != names.init &&
 957                         t.name != names.clinit &&
 958                         (t.flags() & SYNTHETIC) == 0;
 959             }
 960         };
 961 
 962         private boolean pendingBridges(ClassSymbol origin, TypeSymbol s) {
 963             //a symbol will be completed from a classfile if (a) symbol has
 964             //an associated file object with CLASS kind and (b) the symbol has
 965             //not been entered
 966             if (origin.classfile != null &&
 967                     origin.classfile.getKind() == JavaFileObject.Kind.CLASS &&
 968                     enter.getEnv(origin) == null) {
 969                 return false;
 970             }
 971             if (origin == s) {
 972                 return true;
 973             }
 974             for (Type t : interfaces(origin.type)) {
 975                 if (pendingBridges((ClassSymbol)t.tsym, s)) {
 976                     return true;

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












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

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

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

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









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

1403                     return visit(t, wildUpperBound(s)) && visit(t, wildLowerBound(s));
1404 
1405                 if (t.isCompound() && s.isCompound()) {
1406                     if (!visit(supertype(t), supertype(s)))
1407                         return false;
1408 
1409                     Map<Symbol,Type> tMap = new HashMap<>();
1410                     for (Type ti : interfaces(t)) {
1411                         tMap.put(ti.tsym, ti);
1412                     }
1413                     for (Type si : interfaces(s)) {
1414                         if (!tMap.containsKey(si.tsym))
1415                             return false;
1416                         Type ti = tMap.remove(si.tsym);
1417                         if (!visit(ti, si))
1418                             return false;
1419                     }
1420                     return tMap.isEmpty();
1421                 }
1422                 return t.tsym == s.tsym
1423                     && visit(t.getEnclosingType(), s.getEnclosingType())

1424                     && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments());
1425             }








1426 
1427             @Override
1428             public Boolean visitArrayType(ArrayType t, Type s) {
1429                 if (t == s)
1430                     return true;
1431 
1432                 if (s.isPartial())
1433                     return visit(s, t);
1434 
1435                 return s.hasTag(ARRAY)
1436                     && containsTypeEquivalent(t.elemtype, elemtype(s));
1437             }
1438 
1439             @Override
1440             public Boolean visitMethodType(MethodType t, Type s) {
1441                 // isSameType for methods does not take thrown
1442                 // exceptions into account!
1443                 return hasSameArgs(t, s) && visit(t.getReturnType(), s.getReturnType());
1444             }
1445 

1565 //            void debugContainsType(WildcardType t, Type s) {
1566 //                System.err.println();
1567 //                System.err.format(" does %s contain %s?%n", t, s);
1568 //                System.err.format(" %s U(%s) <: U(%s) %s = %s%n",
1569 //                                  wildUpperBound(s), s, t, wildUpperBound(t),
1570 //                                  t.isSuperBound()
1571 //                                  || isSubtypeNoCapture(wildUpperBound(s), wildUpperBound(t)));
1572 //                System.err.format(" %s L(%s) <: L(%s) %s = %s%n",
1573 //                                  wildLowerBound(t), t, s, wildLowerBound(s),
1574 //                                  t.isExtendsBound()
1575 //                                  || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s)));
1576 //                System.err.println();
1577 //            }
1578 
1579             @Override
1580             public Boolean visitWildcardType(WildcardType t, Type s) {
1581                 if (s.isPartial())
1582                     return containedBy(s, t);
1583                 else {
1584 //                    debugContainsType(t, s);









1585                     return isSameWildcard(t, s)
1586                         || isCaptureOf(s, t)
1587                         || ((t.isExtendsBound() || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s))) &&
1588                             (t.isSuperBound() || isSubtypeNoCapture(wildUpperBound(s), wildUpperBound(t))));
1589                 }
1590             }
1591 
1592             @Override
1593             public Boolean visitUndetVar(UndetVar t, Type s) {
1594                 if (!s.hasTag(WILDCARD)) {
1595                     return isSameType(t, s);
1596                 } else {
1597                     return false;
1598                 }
1599             }
1600 
1601             @Override
1602             public Boolean visitErrorType(ErrorType t, Type s) {
1603                 return true;
1604             }

1654                 warnStack = warnStack.prepend(warn);
1655                 checkUnsafeVarargsConversion(t, s, warn);
1656                 result = isCastable.visit(t,s);
1657             } finally {
1658                 warnStack = warnStack.tail;
1659             }
1660         } else {
1661             result = isCastable.visit(t,s);
1662         }
1663         if (result && t.hasTag(CLASS) && t.tsym.kind.matches(Kinds.KindSelector.TYP)
1664                 && s.hasTag(CLASS) && s.tsym.kind.matches(Kinds.KindSelector.TYP)
1665                 && (t.tsym.isSealed() || s.tsym.isSealed())) {
1666             return (t.isCompound() || s.isCompound()) ?
1667                     true :
1668                     !areDisjoint((ClassSymbol)t.tsym, (ClassSymbol)s.tsym);
1669         }
1670         return result;
1671     }
1672     // where
1673         private boolean areDisjoint(ClassSymbol ts, ClassSymbol ss) {
1674             if (isSubtype(erasure(ts.type), erasure(ss.type))) {
1675                 return false;
1676             }
1677             // if both are classes or both are interfaces, shortcut
1678             if (ts.isInterface() == ss.isInterface() && isSubtype(erasure(ss.type), erasure(ts.type))) {
1679                 return false;
1680             }
1681             if (ts.isInterface() && !ss.isInterface()) {
1682                 /* so ts is interface but ss is a class
1683                  * an interface is disjoint from a class if the class is disjoint form the interface
1684                  */
1685                 return areDisjoint(ss, ts);
1686             }
1687             // a final class that is not subtype of ss is disjoint
1688             if (!ts.isInterface() && ts.isFinal()) {
1689                 return true;
1690             }
1691             // if at least one is sealed
1692             if (ts.isSealed() || ss.isSealed()) {
1693                 // permitted subtypes have to be disjoint with the other symbol
1694                 ClassSymbol sealedOne = ts.isSealed() ? ts : ss;

1709                 case DOUBLE:
1710                     return s.isNumeric();
1711                 case BOOLEAN:
1712                     return s.hasTag(BOOLEAN);
1713                 case VOID:
1714                     return false;
1715                 case BOT:
1716                     return isSubtype(t, s);
1717                 default:
1718                     throw new AssertionError();
1719                 }
1720             }
1721 
1722             @Override
1723             public Boolean visitWildcardType(WildcardType t, Type s) {
1724                 return isCastable(wildUpperBound(t), s, warnStack.head);
1725             }
1726 
1727             @Override
1728             public Boolean visitClassType(ClassType t, Type s) {
1729                 if (s.hasTag(ERROR) || s.hasTag(BOT))
1730                     return true;
1731 
1732                 if (s.hasTag(TYPEVAR)) {
1733                     if (isCastable(t, s.getUpperBound(), noWarnings)) {
1734                         warnStack.head.warn(LintCategory.UNCHECKED);
1735                         return true;
1736                     } else {
1737                         return false;
1738                     }
1739                 }
1740 
1741                 if (t.isCompound() || s.isCompound()) {
1742                     return !t.isCompound() ?
1743                             visitCompoundType((ClassType)s, t, true) :
1744                             visitCompoundType(t, s, false);
1745                 }
1746 
1747                 if (s.hasTag(CLASS) || s.hasTag(ARRAY)) {










1748                     boolean upcast;
1749                     if ((upcast = isSubtype(erasure(t), erasure(s)))
1750                         || isSubtype(erasure(s), erasure(t))) {
1751                         if (!upcast && s.hasTag(ARRAY)) {
1752                             if (!isReifiable(s))
1753                                 warnStack.head.warn(LintCategory.UNCHECKED);
1754                             return true;
1755                         } else if (s.isRaw()) {
1756                             return true;
1757                         } else if (t.isRaw()) {
1758                             if (!isUnbounded(s))
1759                                 warnStack.head.warn(LintCategory.UNCHECKED);
1760                             return true;
1761                         }
1762                         // Assume |a| <: |b|
1763                         final Type a = upcast ? t : s;
1764                         final Type b = upcast ? s : t;
1765                         final boolean HIGH = true;
1766                         final boolean LOW = false;
1767                         final boolean DONT_REWRITE_TYPEVARS = false;

2121      * @return the ArrayType for the given component
2122      */
2123     public ArrayType makeArrayType(Type t) {
2124         if (t.hasTag(VOID) || t.hasTag(PACKAGE)) {
2125             Assert.error("Type t must not be a VOID or PACKAGE type, " + t.toString());
2126         }
2127         return new ArrayType(t, syms.arrayClass);
2128     }
2129     // </editor-fold>
2130 
2131     // <editor-fold defaultstate="collapsed" desc="asSuper">
2132     /**
2133      * Return the (most specific) base type of t that starts with the
2134      * given symbol.  If none exists, return null.
2135      *
2136      * Caveat Emptor: Since javac represents the class of all arrays with a singleton
2137      * symbol Symtab.arrayClass, which by being a singleton cannot hold any discriminant,
2138      * this method could yield surprising answers when invoked on arrays. For example when
2139      * invoked with t being byte [] and sym being t.sym itself, asSuper would answer null.
2140      *





























2141      * @param t a type
2142      * @param sym a symbol
2143      */
2144     public Type asSuper(Type t, Symbol sym) {
2145         /* Some examples:
2146          *
2147          * (Enum<E>, Comparable) => Comparable<E>
2148          * (c.s.s.d.AttributeTree.ValueKind, Enum) => Enum<c.s.s.d.AttributeTree.ValueKind>
2149          * (c.s.s.t.ExpressionTree, c.s.s.t.Tree) => c.s.s.t.Tree
2150          * (j.u.List<capture#160 of ? extends c.s.s.d.DocTree>, Iterable) =>
2151          *     Iterable<capture#160 of ? extends c.s.s.d.DocTree>
2152          */






2153         if (sym.type == syms.objectType) { //optimization
2154             return syms.objectType;
2155         }
2156         return asSuper.visit(t, sym);
2157     }
2158     // where
2159         private SimpleVisitor<Type,Symbol> asSuper = new SimpleVisitor<Type,Symbol>() {
2160 
2161             private Set<Symbol> seenTypes = new HashSet<>();
2162 
2163             public Type visitType(Type t, Symbol sym) {
2164                 return null;
2165             }
2166 
2167             @Override
2168             public Type visitClassType(ClassType t, Symbol sym) {
2169                 if (t.tsym == sym)
2170                     return t;
2171 
2172                 Symbol c = t.tsym;

2263         case ARRAY:
2264             return isSubtype(t, sym.type) ? sym.type : null;
2265         case TYPEVAR:
2266             return asSuper(t, sym);
2267         case ERROR:
2268             return t;
2269         default:
2270             return null;
2271         }
2272     }
2273     // </editor-fold>
2274 
2275     // <editor-fold defaultstate="collapsed" desc="memberType">
2276     /**
2277      * The type of given symbol, seen as a member of t.
2278      *
2279      * @param t a type
2280      * @param sym a symbol
2281      */
2282     public Type memberType(Type t, Symbol sym) {
2283         return (sym.flags() & STATIC) != 0
2284             ? sym.type
2285             : memberType.visit(t, sym);









2286         }
2287     // where
2288         private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
2289 
2290             public Type visitType(Type t, Symbol sym) {
2291                 return sym.type;
2292             }
2293 
2294             @Override
2295             public Type visitWildcardType(WildcardType t, Symbol sym) {
2296                 return memberType(wildUpperBound(t), sym);
2297             }
2298 
2299             @Override
2300             public Type visitClassType(ClassType t, Symbol sym) {
2301                 Symbol owner = sym.owner;
2302                 long flags = sym.flags();
2303                 if (((flags & STATIC) == 0) && owner.type.isParameterized()) {
2304                     Type base = asOuterSuper(t, owner);
2305                     //if t is an intersection type T = CT & I1 & I2 ... & In

2418                 }
2419             }
2420 
2421             public Type visitType(Type t, Boolean recurse) {
2422                 if (t.isPrimitive())
2423                     return t; /*fast special case*/
2424                 else {
2425                     //other cases already handled
2426                     return combineMetadata(t, t);
2427                 }
2428             }
2429 
2430             @Override
2431             public Type visitWildcardType(WildcardType t, Boolean recurse) {
2432                 Type erased = erasure(wildUpperBound(t), recurse);
2433                 return combineMetadata(erased, t);
2434             }
2435 
2436             @Override
2437             public Type visitClassType(ClassType t, Boolean recurse) {
2438                 Type erased = t.tsym.erasure(Types.this);
2439                 if (recurse) {
2440                     erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym,
2441                             t.dropMetadata(Annotations.class).getMetadata());
2442                     return erased;
2443                 } else {
2444                     return combineMetadata(erased, t);












2445                 }
2446             }
2447 
2448             @Override
2449             public Type visitTypeVar(TypeVar t, Boolean recurse) {
2450                 Type erased = erasure(t.getUpperBound(), recurse);
2451                 return combineMetadata(erased, t);
2452             }
2453         };
2454 
2455     public List<Type> erasure(List<Type> ts) {
2456         return erasure.visit(ts, false);
2457     }
2458 
2459     public Type erasureRecursive(Type t) {
2460         return erasure(t, true);
2461     }
2462 
2463     public List<Type> erasureRecursive(List<Type> ts) {
2464         return erasure.visit(ts, true);
2465     }
2466     // </editor-fold>

2746     /**
2747      * If the given type is a (possibly selected) type variable,
2748      * return the bounding class of this type, otherwise return the
2749      * type itself.
2750      */
2751     public Type classBound(Type t) {
2752         return classBound.visit(t);
2753     }
2754     // where
2755         private UnaryVisitor<Type> classBound = new UnaryVisitor<Type>() {
2756 
2757             public Type visitType(Type t, Void ignored) {
2758                 return t;
2759             }
2760 
2761             @Override
2762             public Type visitClassType(ClassType t, Void ignored) {
2763                 Type outer1 = classBound(t.getEnclosingType());
2764                 if (outer1 != t.getEnclosingType())
2765                     return new ClassType(outer1, t.getTypeArguments(), t.tsym,
2766                                          t.getMetadata());
2767                 else
2768                     return t;
2769             }
2770 
2771             @Override
2772             public Type visitTypeVar(TypeVar t, Void ignored) {
2773                 return classBound(supertype(t));
2774             }
2775 
2776             @Override
2777             public Type visitErrorType(ErrorType t, Void ignored) {
2778                 return t;
2779             }
2780         };
2781     // </editor-fold>
2782 
2783     // <editor-fold defaultstate="collapsed" desc="subsignature / override equivalence">
2784     /**
2785      * Returns true iff the first signature is a <em>subsignature</em>
2786      * of the other.  This is <b>not</b> an equivalence

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

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

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

4858 
4859         public UniqueType(Type type, Types types) {
4860             this.type = type;
4861             this.types = types;





4862         }
4863 
4864         public int hashCode() {
4865             return types.hashCode(type);
4866         }
4867 
4868         public boolean equals(Object obj) {
4869             return (obj instanceof UniqueType uniqueType) &&
4870                     types.isSameType(type, uniqueType.type);
4871         }
4872 




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

5091                     break;
5092                 case LONG:
5093                     append('J');
5094                     break;
5095                 case FLOAT:
5096                     append('F');
5097                     break;
5098                 case DOUBLE:
5099                     append('D');
5100                     break;
5101                 case BOOLEAN:
5102                     append('Z');
5103                     break;
5104                 case VOID:
5105                     append('V');
5106                     break;
5107                 case CLASS:
5108                     if (type.isCompound()) {
5109                         reportIllegalSignature(type);
5110                     }
5111                     append('L');



5112                     assembleClassSig(type);
5113                     append(';');
5114                     break;
5115                 case ARRAY:
5116                     ArrayType at = (ArrayType) type;
5117                     append('[');
5118                     assembleSig(at.elemtype);
5119                     break;
5120                 case METHOD:
5121                     MethodType mt = (MethodType) type;
5122                     append('(');
5123                     assembleSig(mt.argtypes);
5124                     append(')');
5125                     assembleSig(mt.restype);
5126                     if (hasTypeVar(mt.thrown)) {
5127                         for (List<Type> l = mt.thrown; l.nonEmpty(); l = l.tail) {
5128                             append('^');
5129                             assembleSig(l.head);
5130                         }
5131                     }

  32 import java.util.Map;
  33 import java.util.Optional;
  34 import java.util.Set;
  35 import java.util.WeakHashMap;
  36 import java.util.function.BiPredicate;
  37 import java.util.function.Function;
  38 import java.util.function.Predicate;
  39 import java.util.stream.Collector;
  40 
  41 import javax.tools.JavaFileObject;
  42 
  43 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
  44 import com.sun.tools.javac.code.Lint.LintCategory;
  45 import com.sun.tools.javac.code.Source.Feature;
  46 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
  47 import com.sun.tools.javac.code.TypeMetadata.Annotations;
  48 import com.sun.tools.javac.comp.AttrContext;
  49 import com.sun.tools.javac.comp.Check;
  50 import com.sun.tools.javac.comp.Enter;
  51 import com.sun.tools.javac.comp.Env;

  52 import com.sun.tools.javac.jvm.ClassFile;
  53 import com.sun.tools.javac.util.*;
  54 
  55 import static com.sun.tools.javac.code.BoundKind.*;
  56 import static com.sun.tools.javac.code.Flags.*;
  57 import static com.sun.tools.javac.code.Kinds.Kind.*;
  58 import static com.sun.tools.javac.code.Scope.*;
  59 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
  60 import static com.sun.tools.javac.code.Symbol.*;
  61 import static com.sun.tools.javac.code.Type.*;
  62 import static com.sun.tools.javac.code.TypeTag.*;
  63 import static com.sun.tools.javac.jvm.ClassFile.externalize;
  64 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  65 
  66 /**
  67  * Utility class containing various operations on types.
  68  *
  69  * <p>Unless other names are more illustrative, the following naming
  70  * conventions should be observed in this file:
  71  *

  74  * <dd>If the first argument to an operation is a type, it should be named t.</dd>
  75  * <dt>s</dt>
  76  * <dd>Similarly, if the second argument to an operation is a type, it should be named s.</dd>
  77  * <dt>ts</dt>
  78  * <dd>If an operations takes a list of types, the first should be named ts.</dd>
  79  * <dt>ss</dt>
  80  * <dd>A second list of types should be named ss.</dd>
  81  * </dl>
  82  *
  83  * <p><b>This is NOT part of any supported API.
  84  * If you write code that depends on this, you do so at your own risk.
  85  * This code and its internal interfaces are subject to change or
  86  * deletion without notice.</b>
  87  */
  88 public class Types {
  89     protected static final Context.Key<Types> typesKey = new Context.Key<>();
  90 
  91     final Symtab syms;
  92     final JavacMessages messages;
  93     final Names names;
  94     final boolean allowPrimitiveClasses;
  95     final Check chk;
  96     final Enter enter;
  97     JCDiagnostic.Factory diags;
  98     List<Warner> warnStack = List.nil();
  99     final Name capturedName;
 100 
 101     public final Warner noWarnings;
 102 
 103     // <editor-fold defaultstate="collapsed" desc="Instantiating">
 104     public static Types instance(Context context) {
 105         Types instance = context.get(typesKey);
 106         if (instance == null)
 107             instance = new Types(context);
 108         return instance;
 109     }
 110 
 111     @SuppressWarnings("this-escape")
 112     protected Types(Context context) {
 113         context.put(typesKey, this);
 114         syms = Symtab.instance(context);
 115         names = Names.instance(context);
 116         Source source = Source.instance(context);
 117         chk = Check.instance(context);
 118         enter = Enter.instance(context);
 119         capturedName = names.fromString("<captured wildcard>");
 120         messages = JavacMessages.instance(context);
 121         diags = JCDiagnostic.Factory.instance(context);
 122         noWarnings = new Warner(null);
 123         Options options = Options.instance(context);
 124         allowPrimitiveClasses = Feature.PRIMITIVE_CLASSES.allowedInSource(source) && options.isSet("enablePrimitiveClasses");
 125     }
 126     // </editor-fold>
 127 
 128     // <editor-fold defaultstate="collapsed" desc="bounds">
 129     /**
 130      * Get a wildcard's upper bound, returning non-wildcards unchanged.
 131      * @param t a type argument, either a wildcard or a type
 132      */
 133     public Type wildUpperBound(Type t) {
 134         if (t.hasTag(WILDCARD)) {
 135             WildcardType w = (WildcardType) t;
 136             if (w.isSuperBound())
 137                 return w.bound == null ? syms.objectType : w.bound.getUpperBound();
 138             else
 139                 return wildUpperBound(w.type);
 140         }
 141         else return t;
 142     }
 143 
 144     /**

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

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

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

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

 961             else if (descSym.overrides(m2, origin, Types.this, false)) {
 962                 for (Symbol m3 : overridden) {
 963                     if (isSameType(m3.erasure(Types.this), m2.erasure(Types.this)) ||
 964                             (m3.overrides(m2, origin, Types.this, false) &&
 965                             (pendingBridges((ClassSymbol)origin, m3.enclClass()) ||
 966                             (((MethodSymbol)m2).binaryImplementation((ClassSymbol)m3.owner, Types.this) != null)))) {
 967                         continue outer;
 968                     }
 969                 }
 970                 overridden.add(m2);
 971             }
 972         }
 973         return overridden.toList();
 974     }
 975     //where
 976         // Use anonymous class instead of lambda expression intentionally,
 977         // because the variable `names` has modifier: final.
 978         private Predicate<Symbol> bridgeFilter = new Predicate<Symbol>() {
 979             public boolean test(Symbol t) {
 980                 return t.kind == MTH &&
 981                         !names.isInitOrVNew(t.name) &&
 982                         t.name != names.clinit &&
 983                         (t.flags() & SYNTHETIC) == 0;
 984             }
 985         };
 986 
 987         private boolean pendingBridges(ClassSymbol origin, TypeSymbol s) {
 988             //a symbol will be completed from a classfile if (a) symbol has
 989             //an associated file object with CLASS kind and (b) the symbol has
 990             //not been entered
 991             if (origin.classfile != null &&
 992                     origin.classfile.getKind() == JavaFileObject.Kind.CLASS &&
 993                     enter.getEnv(origin) == null) {
 994                 return false;
 995             }
 996             if (origin == s) {
 997                 return true;
 998             }
 999             for (Type t : interfaces(origin.type)) {
1000                 if (pendingBridges((ClassSymbol)t.tsym, s)) {
1001                     return true;

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

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

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

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

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

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

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

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

2373         case ARRAY:
2374             return isSubtype(t, sym.type) ? sym.type : null;
2375         case TYPEVAR:
2376             return asSuper(t, sym);
2377         case ERROR:
2378             return t;
2379         default:
2380             return null;
2381         }
2382     }
2383     // </editor-fold>
2384 
2385     // <editor-fold defaultstate="collapsed" desc="memberType">
2386     /**
2387      * The type of given symbol, seen as a member of t.
2388      *
2389      * @param t a type
2390      * @param sym a symbol
2391      */
2392     public Type memberType(Type t, Symbol sym) {
2393 
2394         if ((sym.flags() & STATIC) != 0)
2395             return sym.type;
2396 
2397         /* If any primitive class types are involved, switch over to the reference universe,
2398            where the hierarchy is navigable. V and V.ref have identical membership
2399            with no bridging needs.
2400         */
2401         if (allowPrimitiveClasses && t.isPrimitiveClass())
2402             t = t.referenceProjection();
2403 
2404         return memberType.visit(t, sym);
2405         }
2406     // where
2407         private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
2408 
2409             public Type visitType(Type t, Symbol sym) {
2410                 return sym.type;
2411             }
2412 
2413             @Override
2414             public Type visitWildcardType(WildcardType t, Symbol sym) {
2415                 return memberType(wildUpperBound(t), sym);
2416             }
2417 
2418             @Override
2419             public Type visitClassType(ClassType t, Symbol sym) {
2420                 Symbol owner = sym.owner;
2421                 long flags = sym.flags();
2422                 if (((flags & STATIC) == 0) && owner.type.isParameterized()) {
2423                     Type base = asOuterSuper(t, owner);
2424                     //if t is an intersection type T = CT & I1 & I2 ... & In

2537                 }
2538             }
2539 
2540             public Type visitType(Type t, Boolean recurse) {
2541                 if (t.isPrimitive())
2542                     return t; /*fast special case*/
2543                 else {
2544                     //other cases already handled
2545                     return combineMetadata(t, t);
2546                 }
2547             }
2548 
2549             @Override
2550             public Type visitWildcardType(WildcardType t, Boolean recurse) {
2551                 Type erased = erasure(wildUpperBound(t), recurse);
2552                 return combineMetadata(erased, t);
2553             }
2554 
2555             @Override
2556             public Type visitClassType(ClassType t, Boolean recurse) {
2557                 // erasure(projection(primitive)) = projection(erasure(primitive))
2558                 Type erased = eraseClassType(t, recurse);
2559                 if (erased.hasTag(CLASS) && t.flavor != erased.getFlavor()) {
2560                     erased = new ClassType(erased.getEnclosingType(),
2561                             List.nil(), erased.tsym,
2562                             erased.getMetadata(), t.flavor);
2563                 }
2564                 return erased;
2565             }
2566                 // where
2567                 private Type eraseClassType(ClassType t, Boolean recurse) {
2568                     Type erased = t.tsym.erasure(Types.this);
2569                     if (recurse) {
2570                         erased = new ErasedClassType(erased.getEnclosingType(), erased.tsym,
2571                                                      t.dropMetadata(Annotations.class).getMetadata());
2572                         return erased;
2573                     } else {
2574                         return combineMetadata(erased, t);
2575                     }
2576                 }

2577 
2578             @Override
2579             public Type visitTypeVar(TypeVar t, Boolean recurse) {
2580                 Type erased = erasure(t.getUpperBound(), recurse);
2581                 return combineMetadata(erased, t);
2582             }
2583         };
2584 
2585     public List<Type> erasure(List<Type> ts) {
2586         return erasure.visit(ts, false);
2587     }
2588 
2589     public Type erasureRecursive(Type t) {
2590         return erasure(t, true);
2591     }
2592 
2593     public List<Type> erasureRecursive(List<Type> ts) {
2594         return erasure.visit(ts, true);
2595     }
2596     // </editor-fold>

2876     /**
2877      * If the given type is a (possibly selected) type variable,
2878      * return the bounding class of this type, otherwise return the
2879      * type itself.
2880      */
2881     public Type classBound(Type t) {
2882         return classBound.visit(t);
2883     }
2884     // where
2885         private UnaryVisitor<Type> classBound = new UnaryVisitor<Type>() {
2886 
2887             public Type visitType(Type t, Void ignored) {
2888                 return t;
2889             }
2890 
2891             @Override
2892             public Type visitClassType(ClassType t, Void ignored) {
2893                 Type outer1 = classBound(t.getEnclosingType());
2894                 if (outer1 != t.getEnclosingType())
2895                     return new ClassType(outer1, t.getTypeArguments(), t.tsym,
2896                                          t.getMetadata(), t.getFlavor());
2897                 else
2898                     return t;
2899             }
2900 
2901             @Override
2902             public Type visitTypeVar(TypeVar t, Void ignored) {
2903                 return classBound(supertype(t));
2904             }
2905 
2906             @Override
2907             public Type visitErrorType(ErrorType t, Void ignored) {
2908                 return t;
2909             }
2910         };
2911     // </editor-fold>
2912 
2913     // <editor-fold defaultstate="collapsed" desc="subsignature / override equivalence">
2914     /**
2915      * Returns true iff the first signature is a <em>subsignature</em>
2916      * of the other.  This is <b>not</b> an equivalence

3997                         m = new WildcardType(lub(wildUpperBound(act1.head),
3998                                                  wildUpperBound(act2.head)),
3999                                              BoundKind.EXTENDS,
4000                                              syms.boundClass);
4001                         mergeCache.remove(pair);
4002                     } else {
4003                         m = new WildcardType(syms.objectType,
4004                                              BoundKind.UNBOUND,
4005                                              syms.boundClass);
4006                     }
4007                     merged.append(m.withTypeVar(typarams.head));
4008                 }
4009                 act1 = act1.tail;
4010                 act2 = act2.tail;
4011                 typarams = typarams.tail;
4012             }
4013             Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
4014             // There is no spec detailing how type annotations are to
4015             // be inherited.  So set it to noAnnotations for now
4016             return new ClassType(class1.getEnclosingType(), merged.toList(),
4017                                  class1.tsym, List.nil(), class1.getFlavor());
4018         }
4019 
4020     /**
4021      * Return the minimum type of a closure, a compound type if no
4022      * unique minimum exists.
4023      */
4024     private Type compoundMin(List<Type> cl) {
4025         if (cl.isEmpty()) return syms.objectType;
4026         List<Type> compound = closureMin(cl);
4027         if (compound.isEmpty())
4028             return null;
4029         else if (compound.tail.isEmpty())
4030             return compound.head;
4031         else
4032             return makeIntersectionType(compound);
4033     }
4034 
4035     /**
4036      * Return the minimum types of a closure, suitable for computing
4037      * compoundMin or glb.

4557                     Si.lower = Ti.getSuperBound();
4558                     break;
4559                 }
4560                 Type tmpBound = Si.getUpperBound().hasTag(UNDETVAR) ? ((UndetVar)Si.getUpperBound()).qtype : Si.getUpperBound();
4561                 Type tmpLower = Si.lower.hasTag(UNDETVAR) ? ((UndetVar)Si.lower).qtype : Si.lower;
4562                 if (!Si.getUpperBound().hasTag(ERROR) &&
4563                     !Si.lower.hasTag(ERROR) &&
4564                     isSameType(tmpBound, tmpLower)) {
4565                     currentS.head = Si.getUpperBound();
4566                 }
4567             }
4568             currentA = currentA.tail;
4569             currentT = currentT.tail;
4570             currentS = currentS.tail;
4571         }
4572         if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty())
4573             return erasure(t); // some "rare" type involved
4574 
4575         if (captured)
4576             return new ClassType(cls.getEnclosingType(), S, cls.tsym,
4577                                  cls.getMetadata(), cls.getFlavor());
4578         else
4579             return t;
4580     }
4581     // where
4582         public List<Type> freshTypeVariables(List<Type> types) {
4583             ListBuffer<Type> result = new ListBuffer<>();
4584             for (Type t : types) {
4585                 if (t.hasTag(WILDCARD)) {
4586                     Type bound = ((WildcardType)t).getExtendsBound();
4587                     if (bound == null)
4588                         bound = syms.objectType;
4589                     result.append(new CapturedType(capturedName,
4590                                                    syms.noSymbol,
4591                                                    bound,
4592                                                    syms.botType,
4593                                                    (WildcardType)t));
4594                 } else {
4595                     result.append(t);
4596                 }
4597             }

4968     private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
4969         if (bound.hasTag(BOT)) {
4970             return new WildcardType(syms.objectType,
4971                                     BoundKind.UNBOUND,
4972                                     syms.boundClass,
4973                                     formal);
4974         } else {
4975             return new WildcardType(bound,
4976                                     BoundKind.SUPER,
4977                                     syms.boundClass,
4978                                     formal);
4979         }
4980     }
4981 
4982     /**
4983      * A wrapper for a type that allows use in sets.
4984      */
4985     public static class UniqueType {
4986         public final Type type;
4987         final Types types;
4988         private boolean encodeTypeSig;
4989 
4990         public UniqueType(Type type, Types types, boolean encodeTypeSig) {
4991             this.type = type;
4992             this.types = types;
4993             this.encodeTypeSig = encodeTypeSig;
4994         }
4995 
4996         public UniqueType(Type type, Types types) {
4997             this(type, types, true);
4998         }
4999 
5000         public int hashCode() {
5001             return types.hashCode(type);
5002         }
5003 
5004         public boolean equals(Object obj) {
5005             return (obj instanceof UniqueType uniqueType) &&
5006                     types.isSameType(type, uniqueType.type);
5007         }
5008 
5009         public boolean encodeTypeSig() {
5010             return encodeTypeSig;
5011         }
5012 
5013         public String toString() {
5014             return type.toString();
5015         }
5016 
5017     }
5018     // </editor-fold>
5019 
5020     // <editor-fold defaultstate="collapsed" desc="Visitors">
5021     /**
5022      * A default visitor for types.  All visitor methods except
5023      * visitType are implemented by delegating to visitType.  Concrete
5024      * subclasses must provide an implementation of visitType and can
5025      * override other methods as needed.
5026      *
5027      * @param <R> the return type of the operation implemented by this
5028      * visitor; use Void if no return type is needed.
5029      * @param <S> the type of the second argument (the first being the
5030      * type itself) of the operation implemented by this visitor; use
5031      * Void if a second argument is not needed.
5032      */

5231                     break;
5232                 case LONG:
5233                     append('J');
5234                     break;
5235                 case FLOAT:
5236                     append('F');
5237                     break;
5238                 case DOUBLE:
5239                     append('D');
5240                     break;
5241                 case BOOLEAN:
5242                     append('Z');
5243                     break;
5244                 case VOID:
5245                     append('V');
5246                     break;
5247                 case CLASS:
5248                     if (type.isCompound()) {
5249                         reportIllegalSignature(type);
5250                     }
5251                     if (types.allowPrimitiveClasses && type.isPrimitiveClass())
5252                         append('Q');
5253                     else
5254                         append('L');
5255                     assembleClassSig(type);
5256                     append(';');
5257                     break;
5258                 case ARRAY:
5259                     ArrayType at = (ArrayType) type;
5260                     append('[');
5261                     assembleSig(at.elemtype);
5262                     break;
5263                 case METHOD:
5264                     MethodType mt = (MethodType) type;
5265                     append('(');
5266                     assembleSig(mt.argtypes);
5267                     append(')');
5268                     assembleSig(mt.restype);
5269                     if (hasTypeVar(mt.thrown)) {
5270                         for (List<Type> l = mt.thrown; l.nonEmpty(); l = l.tail) {
5271                             append('^');
5272                             assembleSig(l.head);
5273                         }
5274                     }
< prev index next >