< prev index next >

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

Print this page

  26 package com.sun.tools.javac.code;
  27 
  28 import java.lang.ref.SoftReference;
  29 import java.util.HashSet;
  30 import java.util.HashMap;
  31 import java.util.Locale;
  32 import java.util.Map;
  33 import java.util.Optional;
  34 import java.util.Set;
  35 import java.util.WeakHashMap;
  36 import java.util.function.BiPredicate;
  37 import java.util.function.Function;
  38 import java.util.function.Predicate;
  39 import java.util.stream.Collector;
  40 
  41 import javax.tools.JavaFileObject;
  42 
  43 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
  44 import com.sun.tools.javac.code.Lint.LintCategory;
  45 import com.sun.tools.javac.code.Source.Feature;

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

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

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


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

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

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









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

 981     * Scope filter used to skip methods that should be ignored (such as methods
 982     * overridden by j.l.Object) during function interface conversion interface check
 983     */
 984     class DescriptorFilter implements Predicate<Symbol> {
 985 
 986        TypeSymbol origin;
 987 
 988        DescriptorFilter(TypeSymbol origin) {
 989            this.origin = origin;
 990        }
 991 
 992        @Override
 993        public boolean test(Symbol sym) {
 994            return sym.kind == MTH &&
 995                    (sym.flags() & (ABSTRACT | DEFAULT)) == ABSTRACT &&
 996                    !overridesObjectMethod(origin, sym) &&
 997                    (interfaceCandidates(origin.type, (MethodSymbol)sym).head.flags() & DEFAULT) == 0;
 998        }
 999     }
1000 




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










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

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

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


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









1201                 }
1202 
1203                 if (s.hasTag(CLASS)) {
1204                     Name sname = s.tsym.getQualifiedName();
1205                     return sname == names.java_lang_Object
1206                         || sname == names.java_lang_Cloneable
1207                         || sname == names.java_io_Serializable;

1208                 }
1209 
1210                 return false;
1211             }
1212 
1213             @Override
1214             public Boolean visitUndetVar(UndetVar t, Type s) {
1215                 //todo: test against origin needed? or replace with substitution?
1216                 if (t == s || t.qtype == s || s.hasTag(ERROR) || s.hasTag(UNKNOWN)) {
1217                     return true;
1218                 } else if (s.hasTag(BOT)) {
1219                     //if 's' is 'null' there's no instantiated type U for which
1220                     //U <: s (but 'null' itself, which is not a valid type)
1221                     return false;
1222                 }
1223 
1224                 t.addBound(InferenceBound.UPPER, s, Types.this);
1225                 return true;
1226             }
1227 

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


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








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

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









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

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








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

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




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

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





























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






2153         if (sym.type == syms.objectType) { //optimization
2154             return syms.objectType;
2155         }



















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

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

























































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

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









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

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




















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

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

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

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

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

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

4065     }
4066     // where
4067         List<Type> erasedSupertypes(Type t) {
4068             ListBuffer<Type> buf = new ListBuffer<>();
4069             for (Type sup : closure(t)) {
4070                 if (sup.hasTag(TYPEVAR)) {
4071                     buf.append(sup);
4072                 } else {
4073                     buf.append(erasure(sup));
4074                 }
4075             }
4076             return buf.toList();
4077         }
4078 
4079         private Type arraySuperType;
4080         private Type arraySuperType() {
4081             // initialized lazily to avoid problems during compiler startup
4082             if (arraySuperType == null) {
4083                 // JLS 10.8: all arrays implement Cloneable and Serializable.
4084                 arraySuperType = makeIntersectionType(List.of(syms.serializableType,
4085                         syms.cloneableType), true);
4086             }
4087             return arraySuperType;
4088         }
4089     // </editor-fold>
4090 
4091     // <editor-fold defaultstate="collapsed" desc="Greatest lower bound">
4092     public Type glb(List<Type> ts) {
4093         Type t1 = ts.head;
4094         for (Type t2 : ts.tail) {
4095             if (t1.isErroneous())
4096                 return t1;
4097             t1 = glb(t1, t2);
4098         }
4099         return t1;
4100     }
4101     //where
4102     public Type glb(Type t, Type s) {
4103         if (s == null)
4104             return t;
4105         else if (t.isPrimitive() || s.isPrimitive())

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

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

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





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




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

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



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

  26 package com.sun.tools.javac.code;
  27 
  28 import java.lang.ref.SoftReference;
  29 import java.util.HashSet;
  30 import java.util.HashMap;
  31 import java.util.Locale;
  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.ClassType.Flavor;
  47 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
  48 import com.sun.tools.javac.code.TypeMetadata.Entry.Kind;
  49 import com.sun.tools.javac.comp.AttrContext;
  50 import com.sun.tools.javac.comp.Check;
  51 import com.sun.tools.javac.comp.Enter;
  52 import com.sun.tools.javac.comp.Env;

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

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

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

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

 993     * Scope filter used to skip methods that should be ignored (such as methods
 994     * overridden by j.l.Object) during function interface conversion interface check
 995     */
 996     class DescriptorFilter implements Predicate<Symbol> {
 997 
 998        TypeSymbol origin;
 999 
1000        DescriptorFilter(TypeSymbol origin) {
1001            this.origin = origin;
1002        }
1003 
1004        @Override
1005        public boolean test(Symbol sym) {
1006            return sym.kind == MTH &&
1007                    (sym.flags() & (ABSTRACT | DEFAULT)) == ABSTRACT &&
1008                    !overridesObjectMethod(origin, sym) &&
1009                    (interfaceCandidates(origin.type, (MethodSymbol)sym).head.flags() & DEFAULT) == 0;
1010        }
1011     }
1012 
1013     public boolean isPrimitiveClass(Type t) {
1014         return t != null && t.isPrimitiveClass();
1015     }
1016 
1017     // <editor-fold defaultstate="collapsed" desc="isSubtype">
1018     /**
1019      * Is t an unchecked subtype of s?
1020      */
1021     public boolean isSubtypeUnchecked(Type t, Type s) {
1022         return isSubtypeUnchecked(t, s, noWarnings);
1023     }
1024     /**
1025      * Is t an unchecked subtype of s?
1026      */
1027     public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) {
1028         boolean result = isSubtypeUncheckedInternal(t, s, true, warn);
1029         if (result) {
1030             checkUnsafeVarargsConversion(t, s, warn);
1031         }
1032         return result;
1033     }
1034     //where
1035         private boolean isSubtypeUncheckedInternal(Type t, Type s, boolean capture, Warner warn) {
1036             if (t.hasTag(ARRAY) && s.hasTag(ARRAY)) {
1037                 if (((ArrayType)t).elemtype.isPrimitive()) {
1038                     return isSameType(elemtype(t), elemtype(s));
1039                 } else {
1040                     // if T.ref <: S, then T[] <: S[]
1041                     Type es = elemtype(s);
1042                     Type et = elemtype(t);
1043                     if (isPrimitiveClass(et)) {
1044                         et = et.referenceProjection();
1045                         if (isPrimitiveClass(es))
1046                             es = es.referenceProjection();  // V <: V, surely
1047                     }
1048                     if (!isSubtypeUncheckedInternal(et, es, false, warn))
1049                         return false;
1050                     return true;
1051                 }
1052             } else if (isSubtype(t, s, capture)) {
1053                 return true;
1054             } else if (t.hasTag(TYPEVAR)) {
1055                 return isSubtypeUncheckedInternal(t.getUpperBound(), s, false, warn);
1056             } else if (!s.isRaw()) {
1057                 Type t2 = asSuper(t, s.tsym);
1058                 if (t2 != null && t2.isRaw()) {
1059                     if (isReifiable(s)) {
1060                         warn.silentWarn(LintCategory.UNCHECKED);
1061                     } else {
1062                         warn.warn(LintCategory.UNCHECKED);
1063                     }
1064                     return true;
1065                 }
1066             }
1067             return false;
1068         }
1069 
1070         private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) {

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

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

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

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

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

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

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

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

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

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

2655 
2656             @Override
2657             public Type visitTypeVar(TypeVar t, Boolean recurse) {
2658                 Type erased = erasure(t.getUpperBound(), recurse);
2659                 return combineMetadata(erased, t);
2660             }
2661         };
2662 
2663     public List<Type> erasure(List<Type> ts) {
2664         return erasure.visit(ts, false);
2665     }
2666 
2667     public Type erasureRecursive(Type t) {
2668         return erasure(t, true);
2669     }
2670 
2671     public List<Type> erasureRecursive(List<Type> ts) {
2672         return erasure.visit(ts, true);
2673     }
2674     // </editor-fold>

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

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

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

4154     }
4155 
4156     /**
4157      * Return the least upper bound of list of types.  if the lub does
4158      * not exist return null.
4159      */
4160     public Type lub(List<Type> ts) {
4161         return lub(ts.toArray(new Type[ts.length()]));
4162     }
4163 
4164     /**
4165      * Return the least upper bound (lub) of set of types.  If the lub
4166      * does not exist return the type of null (bottom).
4167      */
4168     public Type lub(Type... ts) {
4169         final int UNKNOWN_BOUND = 0;
4170         final int ARRAY_BOUND = 1;
4171         final int CLASS_BOUND = 2;
4172 
4173         int[] kinds = new int[ts.length];

4174         int boundkind = UNKNOWN_BOUND;
4175         for (int i = 0 ; i < ts.length ; i++) {
4176             Type t = ts[i];
4177             switch (t.getTag()) {
4178             case CLASS:
4179                 boundkind |= kinds[i] = CLASS_BOUND;
4180                 break;
4181             case ARRAY:
4182                 boundkind |= kinds[i] = ARRAY_BOUND;
4183                 break;
4184             case  TYPEVAR:
4185                 do {
4186                     t = t.getUpperBound();
4187                 } while (t.hasTag(TYPEVAR));
4188                 if (t.hasTag(ARRAY)) {
4189                     boundkind |= kinds[i] = ARRAY_BOUND;
4190                 } else {
4191                     boundkind |= kinds[i] = CLASS_BOUND;
4192                 }
4193                 break;

4273     }
4274     // where
4275         List<Type> erasedSupertypes(Type t) {
4276             ListBuffer<Type> buf = new ListBuffer<>();
4277             for (Type sup : closure(t)) {
4278                 if (sup.hasTag(TYPEVAR)) {
4279                     buf.append(sup);
4280                 } else {
4281                     buf.append(erasure(sup));
4282                 }
4283             }
4284             return buf.toList();
4285         }
4286 
4287         private Type arraySuperType;
4288         private Type arraySuperType() {
4289             // initialized lazily to avoid problems during compiler startup
4290             if (arraySuperType == null) {
4291                 // JLS 10.8: all arrays implement Cloneable and Serializable.
4292                 arraySuperType = makeIntersectionType(List.of(syms.serializableType,
4293                         syms.cloneableType, syms.identityObjectType), true);
4294             }
4295             return arraySuperType;
4296         }
4297     // </editor-fold>
4298 
4299     // <editor-fold defaultstate="collapsed" desc="Greatest lower bound">
4300     public Type glb(List<Type> ts) {
4301         Type t1 = ts.head;
4302         for (Type t2 : ts.tail) {
4303             if (t1.isErroneous())
4304                 return t1;
4305             t1 = glb(t1, t2);
4306         }
4307         return t1;
4308     }
4309     //where
4310     public Type glb(Type t, Type s) {
4311         if (s == null)
4312             return t;
4313         else if (t.isPrimitive() || s.isPrimitive())

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

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

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