< prev index next >

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

Print this page

  32 import java.util.Map;
  33 import java.util.Optional;
  34 import java.util.Set;
  35 import java.util.WeakHashMap;
  36 import java.util.function.BiPredicate;
  37 import java.util.function.Function;
  38 import java.util.function.Predicate;
  39 import java.util.stream.Collector;
  40 
  41 import javax.tools.JavaFileObject;
  42 
  43 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
  44 import com.sun.tools.javac.code.Lint.LintCategory;
  45 import com.sun.tools.javac.code.Source.Feature;
  46 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
  47 import com.sun.tools.javac.code.TypeMetadata.Entry.Kind;
  48 import com.sun.tools.javac.comp.AttrContext;
  49 import com.sun.tools.javac.comp.Check;
  50 import com.sun.tools.javac.comp.Enter;
  51 import com.sun.tools.javac.comp.Env;
  52 import com.sun.tools.javac.comp.LambdaToMethod;
  53 import com.sun.tools.javac.jvm.ClassFile;
  54 import com.sun.tools.javac.util.*;
  55 
  56 import static com.sun.tools.javac.code.BoundKind.*;
  57 import static com.sun.tools.javac.code.Flags.*;
  58 import static com.sun.tools.javac.code.Kinds.Kind.*;
  59 import static com.sun.tools.javac.code.Scope.*;
  60 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
  61 import static com.sun.tools.javac.code.Symbol.*;
  62 import static com.sun.tools.javac.code.Type.*;
  63 import static com.sun.tools.javac.code.TypeTag.*;
  64 import static com.sun.tools.javac.jvm.ClassFile.externalize;
  65 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  66 
  67 /**
  68  * Utility class containing various operations on types.
  69  *
  70  * <p>Unless other names are more illustrative, the following naming
  71  * conventions should be observed in this file:
  72  *

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

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


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

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

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









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

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


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











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

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










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

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

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

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









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

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

1426                     && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments());
1427             }








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

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









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

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

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








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

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




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

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





























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






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

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









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

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












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

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

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

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

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

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

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

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

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





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




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

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



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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2605      */
2606     public IntersectionClassType makeIntersectionType(List<Type> bounds) {
2607         return makeIntersectionType(bounds, bounds.head.tsym.isInterface());
2608     }
2609 
2610     /**
2611      * Make an intersection type from non-empty list of types.  The list should be ordered according to
2612      * {@link TypeSymbol#precedes(TypeSymbol, Types)}. This does not cause symbol completion as
2613      * an extra parameter indicates as to whether all bounds are interfaces - in which case the
2614      * supertype is implicitly assumed to be 'Object'.
2615      *
2616      * @param bounds        the types from which the intersection type is formed
2617      * @param allInterfaces are all bounds interface types?
2618      */
2619     public IntersectionClassType makeIntersectionType(List<Type> bounds, boolean allInterfaces) {
2620         Assert.check(bounds.nonEmpty());
2621         Type firstExplicitBound = bounds.head;
2622         if (allInterfaces) {
2623             bounds = bounds.prepend(syms.objectType);
2624         }
2625         long flags = ABSTRACT | PUBLIC | SYNTHETIC | COMPOUND | ACYCLIC;
2626         ClassSymbol bc =
2627             new ClassSymbol(flags,
2628                             Type.moreInfo
2629                                 ? names.fromString(bounds.toString())
2630                                 : names.empty,
2631                             null,
2632                             syms.noSymbol);
2633         IntersectionClassType intersectionType = new IntersectionClassType(bounds, bc, allInterfaces);
2634         bc.type = intersectionType;
2635         bc.erasure_field = (bounds.head.hasTag(TYPEVAR)) ?
2636                 syms.objectType : // error condition, recover
2637                 erasure(firstExplicitBound);
2638         bc.members_field = WriteableScope.create(bc);
2639         return intersectionType;
2640     }
2641     // </editor-fold>
2642 
2643     // <editor-fold defaultstate="collapsed" desc="supertype">
2644     public Type supertype(Type t) {
2645         return supertype.visit(t);
2646     }
2647     // where

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

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

4070     }
4071 
4072     /**
4073      * Return the least upper bound of list of types.  if the lub does
4074      * not exist return null.
4075      */
4076     public Type lub(List<Type> ts) {
4077         return lub(ts.toArray(new Type[ts.length()]));
4078     }
4079 
4080     /**
4081      * Return the least upper bound (lub) of set of types.  If the lub
4082      * does not exist return the type of null (bottom).
4083      */
4084     public Type lub(Type... ts) {
4085         final int UNKNOWN_BOUND = 0;
4086         final int ARRAY_BOUND = 1;
4087         final int CLASS_BOUND = 2;
4088 
4089         int[] kinds = new int[ts.length];

4090         int boundkind = UNKNOWN_BOUND;
4091         for (int i = 0 ; i < ts.length ; i++) {
4092             Type t = ts[i];
4093             switch (t.getTag()) {
4094             case CLASS:
4095                 boundkind |= kinds[i] = CLASS_BOUND;
4096                 break;
4097             case ARRAY:
4098                 boundkind |= kinds[i] = ARRAY_BOUND;
4099                 break;
4100             case  TYPEVAR:
4101                 do {
4102                     t = t.getUpperBound();
4103                 } while (t.hasTag(TYPEVAR));
4104                 if (t.hasTag(ARRAY)) {
4105                     boundkind |= kinds[i] = ARRAY_BOUND;
4106                 } else {
4107                     boundkind |= kinds[i] = CLASS_BOUND;
4108                 }
4109                 break;

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 (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 >