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

Wed, 02 Jul 2008 12:56:02 -0700

author
xdono
date
Wed, 02 Jul 2008 12:56:02 -0700
changeset 54
eaf608c64fec
parent 41
6e9a43815df7
child 79
36df13bde238
permissions
-rw-r--r--

6719955: Update copyright year
Summary: Update copyright year for files that have been modified in 2008
Reviewed-by: ohair, tbell

     1 /*
     2  * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Sun designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Sun in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
    23  * have any questions.
    24  */
    26 package com.sun.tools.javac.code;
    28 import java.util.*;
    30 import com.sun.tools.javac.util.*;
    31 import com.sun.tools.javac.util.List;
    33 import com.sun.tools.javac.jvm.ClassReader;
    34 import com.sun.tools.javac.comp.Infer;
    35 import com.sun.tools.javac.comp.Check;
    37 import static com.sun.tools.javac.code.Type.*;
    38 import static com.sun.tools.javac.code.TypeTags.*;
    39 import static com.sun.tools.javac.code.Symbol.*;
    40 import static com.sun.tools.javac.code.Flags.*;
    41 import static com.sun.tools.javac.code.BoundKind.*;
    42 import static com.sun.tools.javac.util.ListBuffer.lb;
    44 /**
    45  * Utility class containing various operations on types.
    46  *
    47  * <p>Unless other names are more illustrative, the following naming
    48  * conventions should be observed in this file:
    49  *
    50  * <dl>
    51  * <dt>t</dt>
    52  * <dd>If the first argument to an operation is a type, it should be named t.</dd>
    53  * <dt>s</dt>
    54  * <dd>Similarly, if the second argument to an operation is a type, it should be named s.</dd>
    55  * <dt>ts</dt>
    56  * <dd>If an operations takes a list of types, the first should be named ts.</dd>
    57  * <dt>ss</dt>
    58  * <dd>A second list of types should be named ss.</dd>
    59  * </dl>
    60  *
    61  * <p><b>This is NOT part of any API supported by Sun Microsystems.
    62  * If you write code that depends on this, you do so at your own risk.
    63  * This code and its internal interfaces are subject to change or
    64  * deletion without notice.</b>
    65  */
    66 public class Types {
    67     protected static final Context.Key<Types> typesKey =
    68         new Context.Key<Types>();
    70     final Symtab syms;
    71     final Name.Table names;
    72     final boolean allowBoxing;
    73     final ClassReader reader;
    74     final Source source;
    75     final Check chk;
    76     List<Warner> warnStack = List.nil();
    77     final Name capturedName;
    79     // <editor-fold defaultstate="collapsed" desc="Instantiating">
    80     public static Types instance(Context context) {
    81         Types instance = context.get(typesKey);
    82         if (instance == null)
    83             instance = new Types(context);
    84         return instance;
    85     }
    87     protected Types(Context context) {
    88         context.put(typesKey, this);
    89         syms = Symtab.instance(context);
    90         names = Name.Table.instance(context);
    91         allowBoxing = Source.instance(context).allowBoxing();
    92         reader = ClassReader.instance(context);
    93         source = Source.instance(context);
    94         chk = Check.instance(context);
    95         capturedName = names.fromString("<captured wildcard>");
    96     }
    97     // </editor-fold>
    99     // <editor-fold defaultstate="collapsed" desc="upperBound">
   100     /**
   101      * The "rvalue conversion".<br>
   102      * The upper bound of most types is the type
   103      * itself.  Wildcards, on the other hand have upper
   104      * and lower bounds.
   105      * @param t a type
   106      * @return the upper bound of the given type
   107      */
   108     public Type upperBound(Type t) {
   109         return upperBound.visit(t);
   110     }
   111     // where
   112         private final MapVisitor<Void> upperBound = new MapVisitor<Void>() {
   114             @Override
   115             public Type visitWildcardType(WildcardType t, Void ignored) {
   116                 if (t.isSuperBound())
   117                     return t.bound == null ? syms.objectType : t.bound.bound;
   118                 else
   119                     return visit(t.type);
   120             }
   122             @Override
   123             public Type visitCapturedType(CapturedType t, Void ignored) {
   124                 return visit(t.bound);
   125             }
   126         };
   127     // </editor-fold>
   129     // <editor-fold defaultstate="collapsed" desc="lowerBound">
   130     /**
   131      * The "lvalue conversion".<br>
   132      * The lower bound of most types is the type
   133      * itself.  Wildcards, on the other hand have upper
   134      * and lower bounds.
   135      * @param t a type
   136      * @return the lower bound of the given type
   137      */
   138     public Type lowerBound(Type t) {
   139         return lowerBound.visit(t);
   140     }
   141     // where
   142         private final MapVisitor<Void> lowerBound = new MapVisitor<Void>() {
   144             @Override
   145             public Type visitWildcardType(WildcardType t, Void ignored) {
   146                 return t.isExtendsBound() ? syms.botType : visit(t.type);
   147             }
   149             @Override
   150             public Type visitCapturedType(CapturedType t, Void ignored) {
   151                 return visit(t.getLowerBound());
   152             }
   153         };
   154     // </editor-fold>
   156     // <editor-fold defaultstate="collapsed" desc="isUnbounded">
   157     /**
   158      * Checks that all the arguments to a class are unbounded
   159      * wildcards or something else that doesn't make any restrictions
   160      * on the arguments. If a class isUnbounded, a raw super- or
   161      * subclass can be cast to it without a warning.
   162      * @param t a type
   163      * @return true iff the given type is unbounded or raw
   164      */
   165     public boolean isUnbounded(Type t) {
   166         return isUnbounded.visit(t);
   167     }
   168     // where
   169         private final UnaryVisitor<Boolean> isUnbounded = new UnaryVisitor<Boolean>() {
   171             public Boolean visitType(Type t, Void ignored) {
   172                 return true;
   173             }
   175             @Override
   176             public Boolean visitClassType(ClassType t, Void ignored) {
   177                 List<Type> parms = t.tsym.type.allparams();
   178                 List<Type> args = t.allparams();
   179                 while (parms.nonEmpty()) {
   180                     WildcardType unb = new WildcardType(syms.objectType,
   181                                                         BoundKind.UNBOUND,
   182                                                         syms.boundClass,
   183                                                         (TypeVar)parms.head);
   184                     if (!containsType(args.head, unb))
   185                         return false;
   186                     parms = parms.tail;
   187                     args = args.tail;
   188                 }
   189                 return true;
   190             }
   191         };
   192     // </editor-fold>
   194     // <editor-fold defaultstate="collapsed" desc="asSub">
   195     /**
   196      * Return the least specific subtype of t that starts with symbol
   197      * sym.  If none exists, return null.  The least specific subtype
   198      * is determined as follows:
   199      *
   200      * <p>If there is exactly one parameterized instance of sym that is a
   201      * subtype of t, that parameterized instance is returned.<br>
   202      * Otherwise, if the plain type or raw type `sym' is a subtype of
   203      * type t, the type `sym' itself is returned.  Otherwise, null is
   204      * returned.
   205      */
   206     public Type asSub(Type t, Symbol sym) {
   207         return asSub.visit(t, sym);
   208     }
   209     // where
   210         private final SimpleVisitor<Type,Symbol> asSub = new SimpleVisitor<Type,Symbol>() {
   212             public Type visitType(Type t, Symbol sym) {
   213                 return null;
   214             }
   216             @Override
   217             public Type visitClassType(ClassType t, Symbol sym) {
   218                 if (t.tsym == sym)
   219                     return t;
   220                 Type base = asSuper(sym.type, t.tsym);
   221                 if (base == null)
   222                     return null;
   223                 ListBuffer<Type> from = new ListBuffer<Type>();
   224                 ListBuffer<Type> to = new ListBuffer<Type>();
   225                 try {
   226                     adapt(base, t, from, to);
   227                 } catch (AdaptFailure ex) {
   228                     return null;
   229                 }
   230                 Type res = subst(sym.type, from.toList(), to.toList());
   231                 if (!isSubtype(res, t))
   232                     return null;
   233                 ListBuffer<Type> openVars = new ListBuffer<Type>();
   234                 for (List<Type> l = sym.type.allparams();
   235                      l.nonEmpty(); l = l.tail)
   236                     if (res.contains(l.head) && !t.contains(l.head))
   237                         openVars.append(l.head);
   238                 if (openVars.nonEmpty()) {
   239                     if (t.isRaw()) {
   240                         // The subtype of a raw type is raw
   241                         res = erasure(res);
   242                     } else {
   243                         // Unbound type arguments default to ?
   244                         List<Type> opens = openVars.toList();
   245                         ListBuffer<Type> qs = new ListBuffer<Type>();
   246                         for (List<Type> iter = opens; iter.nonEmpty(); iter = iter.tail) {
   247                             qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head));
   248                         }
   249                         res = subst(res, opens, qs.toList());
   250                     }
   251                 }
   252                 return res;
   253             }
   255             @Override
   256             public Type visitErrorType(ErrorType t, Symbol sym) {
   257                 return t;
   258             }
   259         };
   260     // </editor-fold>
   262     // <editor-fold defaultstate="collapsed" desc="isConvertible">
   263     /**
   264      * Is t a subtype of or convertiable via boxing/unboxing
   265      * convertions to s?
   266      */
   267     public boolean isConvertible(Type t, Type s, Warner warn) {
   268         boolean tPrimitive = t.isPrimitive();
   269         boolean sPrimitive = s.isPrimitive();
   270         if (tPrimitive == sPrimitive)
   271             return isSubtypeUnchecked(t, s, warn);
   272         if (!allowBoxing) return false;
   273         return tPrimitive
   274             ? isSubtype(boxedClass(t).type, s)
   275             : isSubtype(unboxedType(t), s);
   276     }
   278     /**
   279      * Is t a subtype of or convertiable via boxing/unboxing
   280      * convertions to s?
   281      */
   282     public boolean isConvertible(Type t, Type s) {
   283         return isConvertible(t, s, Warner.noWarnings);
   284     }
   285     // </editor-fold>
   287     // <editor-fold defaultstate="collapsed" desc="isSubtype">
   288     /**
   289      * Is t an unchecked subtype of s?
   290      */
   291     public boolean isSubtypeUnchecked(Type t, Type s) {
   292         return isSubtypeUnchecked(t, s, Warner.noWarnings);
   293     }
   294     /**
   295      * Is t an unchecked subtype of s?
   296      */
   297     public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) {
   298         if (t.tag == ARRAY && s.tag == ARRAY) {
   299             return (((ArrayType)t).elemtype.tag <= lastBaseTag)
   300                 ? isSameType(elemtype(t), elemtype(s))
   301                 : isSubtypeUnchecked(elemtype(t), elemtype(s), warn);
   302         } else if (isSubtype(t, s)) {
   303             return true;
   304         }
   305         else if (t.tag == TYPEVAR) {
   306             return isSubtypeUnchecked(t.getUpperBound(), s, warn);
   307         }
   308         else if (!s.isRaw()) {
   309             Type t2 = asSuper(t, s.tsym);
   310             if (t2 != null && t2.isRaw()) {
   311                 if (isReifiable(s))
   312                     warn.silentUnchecked();
   313                 else
   314                     warn.warnUnchecked();
   315                 return true;
   316             }
   317         }
   318         return false;
   319     }
   321     /**
   322      * Is t a subtype of s?<br>
   323      * (not defined for Method and ForAll types)
   324      */
   325     final public boolean isSubtype(Type t, Type s) {
   326         return isSubtype(t, s, true);
   327     }
   328     final public boolean isSubtypeNoCapture(Type t, Type s) {
   329         return isSubtype(t, s, false);
   330     }
   331     public boolean isSubtype(Type t, Type s, boolean capture) {
   332         if (t == s)
   333             return true;
   335         if (s.tag >= firstPartialTag)
   336             return isSuperType(s, t);
   338         Type lower = lowerBound(s);
   339         if (s != lower)
   340             return isSubtype(capture ? capture(t) : t, lower, false);
   342         return isSubtype.visit(capture ? capture(t) : t, s);
   343     }
   344     // where
   345         private TypeRelation isSubtype = new TypeRelation()
   346         {
   347             public Boolean visitType(Type t, Type s) {
   348                 switch (t.tag) {
   349                 case BYTE: case CHAR:
   350                     return (t.tag == s.tag ||
   351                               t.tag + 2 <= s.tag && s.tag <= DOUBLE);
   352                 case SHORT: case INT: case LONG: case FLOAT: case DOUBLE:
   353                     return t.tag <= s.tag && s.tag <= DOUBLE;
   354                 case BOOLEAN: case VOID:
   355                     return t.tag == s.tag;
   356                 case TYPEVAR:
   357                     return isSubtypeNoCapture(t.getUpperBound(), s);
   358                 case BOT:
   359                     return
   360                         s.tag == BOT || s.tag == CLASS ||
   361                         s.tag == ARRAY || s.tag == TYPEVAR;
   362                 case NONE:
   363                     return false;
   364                 default:
   365                     throw new AssertionError("isSubtype " + t.tag);
   366                 }
   367             }
   369             private Set<TypePair> cache = new HashSet<TypePair>();
   371             private boolean containsTypeRecursive(Type t, Type s) {
   372                 TypePair pair = new TypePair(t, s);
   373                 if (cache.add(pair)) {
   374                     try {
   375                         return containsType(t.getTypeArguments(),
   376                                             s.getTypeArguments());
   377                     } finally {
   378                         cache.remove(pair);
   379                     }
   380                 } else {
   381                     return containsType(t.getTypeArguments(),
   382                                         rewriteSupers(s).getTypeArguments());
   383                 }
   384             }
   386             private Type rewriteSupers(Type t) {
   387                 if (!t.isParameterized())
   388                     return t;
   389                 ListBuffer<Type> from = lb();
   390                 ListBuffer<Type> to = lb();
   391                 adaptSelf(t, from, to);
   392                 if (from.isEmpty())
   393                     return t;
   394                 ListBuffer<Type> rewrite = lb();
   395                 boolean changed = false;
   396                 for (Type orig : to.toList()) {
   397                     Type s = rewriteSupers(orig);
   398                     if (s.isSuperBound() && !s.isExtendsBound()) {
   399                         s = new WildcardType(syms.objectType,
   400                                              BoundKind.UNBOUND,
   401                                              syms.boundClass);
   402                         changed = true;
   403                     } else if (s != orig) {
   404                         s = new WildcardType(upperBound(s),
   405                                              BoundKind.EXTENDS,
   406                                              syms.boundClass);
   407                         changed = true;
   408                     }
   409                     rewrite.append(s);
   410                 }
   411                 if (changed)
   412                     return subst(t.tsym.type, from.toList(), rewrite.toList());
   413                 else
   414                     return t;
   415             }
   417             @Override
   418             public Boolean visitClassType(ClassType t, Type s) {
   419                 Type sup = asSuper(t, s.tsym);
   420                 return sup != null
   421                     && sup.tsym == s.tsym
   422                     // You're not allowed to write
   423                     //     Vector<Object> vec = new Vector<String>();
   424                     // But with wildcards you can write
   425                     //     Vector<? extends Object> vec = new Vector<String>();
   426                     // which means that subtype checking must be done
   427                     // here instead of same-type checking (via containsType).
   428                     && (!s.isParameterized() || containsTypeRecursive(s, sup))
   429                     && isSubtypeNoCapture(sup.getEnclosingType(),
   430                                           s.getEnclosingType());
   431             }
   433             @Override
   434             public Boolean visitArrayType(ArrayType t, Type s) {
   435                 if (s.tag == ARRAY) {
   436                     if (t.elemtype.tag <= lastBaseTag)
   437                         return isSameType(t.elemtype, elemtype(s));
   438                     else
   439                         return isSubtypeNoCapture(t.elemtype, elemtype(s));
   440                 }
   442                 if (s.tag == CLASS) {
   443                     Name sname = s.tsym.getQualifiedName();
   444                     return sname == names.java_lang_Object
   445                         || sname == names.java_lang_Cloneable
   446                         || sname == names.java_io_Serializable;
   447                 }
   449                 return false;
   450             }
   452             @Override
   453             public Boolean visitUndetVar(UndetVar t, Type s) {
   454                 //todo: test against origin needed? or replace with substitution?
   455                 if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN)
   456                     return true;
   458                 if (t.inst != null)
   459                     return isSubtypeNoCapture(t.inst, s); // TODO: ", warn"?
   461                 t.hibounds = t.hibounds.prepend(s);
   462                 return true;
   463             }
   465             @Override
   466             public Boolean visitErrorType(ErrorType t, Type s) {
   467                 return true;
   468             }
   469         };
   471     /**
   472      * Is t a subtype of every type in given list `ts'?<br>
   473      * (not defined for Method and ForAll types)<br>
   474      * Allows unchecked conversions.
   475      */
   476     public boolean isSubtypeUnchecked(Type t, List<Type> ts, Warner warn) {
   477         for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
   478             if (!isSubtypeUnchecked(t, l.head, warn))
   479                 return false;
   480         return true;
   481     }
   483     /**
   484      * Are corresponding elements of ts subtypes of ss?  If lists are
   485      * of different length, return false.
   486      */
   487     public boolean isSubtypes(List<Type> ts, List<Type> ss) {
   488         while (ts.tail != null && ss.tail != null
   489                /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
   490                isSubtype(ts.head, ss.head)) {
   491             ts = ts.tail;
   492             ss = ss.tail;
   493         }
   494         return ts.tail == null && ss.tail == null;
   495         /*inlined: ts.isEmpty() && ss.isEmpty();*/
   496     }
   498     /**
   499      * Are corresponding elements of ts subtypes of ss, allowing
   500      * unchecked conversions?  If lists are of different length,
   501      * return false.
   502      **/
   503     public boolean isSubtypesUnchecked(List<Type> ts, List<Type> ss, Warner warn) {
   504         while (ts.tail != null && ss.tail != null
   505                /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
   506                isSubtypeUnchecked(ts.head, ss.head, warn)) {
   507             ts = ts.tail;
   508             ss = ss.tail;
   509         }
   510         return ts.tail == null && ss.tail == null;
   511         /*inlined: ts.isEmpty() && ss.isEmpty();*/
   512     }
   513     // </editor-fold>
   515     // <editor-fold defaultstate="collapsed" desc="isSuperType">
   516     /**
   517      * Is t a supertype of s?
   518      */
   519     public boolean isSuperType(Type t, Type s) {
   520         switch (t.tag) {
   521         case ERROR:
   522             return true;
   523         case UNDETVAR: {
   524             UndetVar undet = (UndetVar)t;
   525             if (t == s ||
   526                 undet.qtype == s ||
   527                 s.tag == ERROR ||
   528                 s.tag == BOT) return true;
   529             if (undet.inst != null)
   530                 return isSubtype(s, undet.inst);
   531             undet.lobounds = undet.lobounds.prepend(s);
   532             return true;
   533         }
   534         default:
   535             return isSubtype(s, t);
   536         }
   537     }
   538     // </editor-fold>
   540     // <editor-fold defaultstate="collapsed" desc="isSameType">
   541     /**
   542      * Are corresponding elements of the lists the same type?  If
   543      * lists are of different length, return false.
   544      */
   545     public boolean isSameTypes(List<Type> ts, List<Type> ss) {
   546         while (ts.tail != null && ss.tail != null
   547                /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
   548                isSameType(ts.head, ss.head)) {
   549             ts = ts.tail;
   550             ss = ss.tail;
   551         }
   552         return ts.tail == null && ss.tail == null;
   553         /*inlined: ts.isEmpty() && ss.isEmpty();*/
   554     }
   556     /**
   557      * Is t the same type as s?
   558      */
   559     public boolean isSameType(Type t, Type s) {
   560         return isSameType.visit(t, s);
   561     }
   562     // where
   563         private TypeRelation isSameType = new TypeRelation() {
   565             public Boolean visitType(Type t, Type s) {
   566                 if (t == s)
   567                     return true;
   569                 if (s.tag >= firstPartialTag)
   570                     return visit(s, t);
   572                 switch (t.tag) {
   573                 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
   574                 case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE:
   575                     return t.tag == s.tag;
   576                 case TYPEVAR:
   577                     return s.isSuperBound()
   578                         && !s.isExtendsBound()
   579                         && visit(t, upperBound(s));
   580                 default:
   581                     throw new AssertionError("isSameType " + t.tag);
   582                 }
   583             }
   585             @Override
   586             public Boolean visitWildcardType(WildcardType t, Type s) {
   587                 if (s.tag >= firstPartialTag)
   588                     return visit(s, t);
   589                 else
   590                     return false;
   591             }
   593             @Override
   594             public Boolean visitClassType(ClassType t, Type s) {
   595                 if (t == s)
   596                     return true;
   598                 if (s.tag >= firstPartialTag)
   599                     return visit(s, t);
   601                 if (s.isSuperBound() && !s.isExtendsBound())
   602                     return visit(t, upperBound(s)) && visit(t, lowerBound(s));
   604                 if (t.isCompound() && s.isCompound()) {
   605                     if (!visit(supertype(t), supertype(s)))
   606                         return false;
   608                     HashSet<SingletonType> set = new HashSet<SingletonType>();
   609                     for (Type x : interfaces(t))
   610                         set.add(new SingletonType(x));
   611                     for (Type x : interfaces(s)) {
   612                         if (!set.remove(new SingletonType(x)))
   613                             return false;
   614                     }
   615                     return (set.size() == 0);
   616                 }
   617                 return t.tsym == s.tsym
   618                     && visit(t.getEnclosingType(), s.getEnclosingType())
   619                     && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments());
   620             }
   622             @Override
   623             public Boolean visitArrayType(ArrayType t, Type s) {
   624                 if (t == s)
   625                     return true;
   627                 if (s.tag >= firstPartialTag)
   628                     return visit(s, t);
   630                 return s.tag == ARRAY
   631                     && containsTypeEquivalent(t.elemtype, elemtype(s));
   632             }
   634             @Override
   635             public Boolean visitMethodType(MethodType t, Type s) {
   636                 // isSameType for methods does not take thrown
   637                 // exceptions into account!
   638                 return hasSameArgs(t, s) && visit(t.getReturnType(), s.getReturnType());
   639             }
   641             @Override
   642             public Boolean visitPackageType(PackageType t, Type s) {
   643                 return t == s;
   644             }
   646             @Override
   647             public Boolean visitForAll(ForAll t, Type s) {
   648                 if (s.tag != FORALL)
   649                     return false;
   651                 ForAll forAll = (ForAll)s;
   652                 return hasSameBounds(t, forAll)
   653                     && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
   654             }
   656             @Override
   657             public Boolean visitUndetVar(UndetVar t, Type s) {
   658                 if (s.tag == WILDCARD)
   659                     // FIXME, this might be leftovers from before capture conversion
   660                     return false;
   662                 if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN)
   663                     return true;
   665                 if (t.inst != null)
   666                     return visit(t.inst, s);
   668                 t.inst = fromUnknownFun.apply(s);
   669                 for (List<Type> l = t.lobounds; l.nonEmpty(); l = l.tail) {
   670                     if (!isSubtype(l.head, t.inst))
   671                         return false;
   672                 }
   673                 for (List<Type> l = t.hibounds; l.nonEmpty(); l = l.tail) {
   674                     if (!isSubtype(t.inst, l.head))
   675                         return false;
   676                 }
   677                 return true;
   678             }
   680             @Override
   681             public Boolean visitErrorType(ErrorType t, Type s) {
   682                 return true;
   683             }
   684         };
   685     // </editor-fold>
   687     // <editor-fold defaultstate="collapsed" desc="fromUnknownFun">
   688     /**
   689      * A mapping that turns all unknown types in this type to fresh
   690      * unknown variables.
   691      */
   692     public Mapping fromUnknownFun = new Mapping("fromUnknownFun") {
   693             public Type apply(Type t) {
   694                 if (t.tag == UNKNOWN) return new UndetVar(t);
   695                 else return t.map(this);
   696             }
   697         };
   698     // </editor-fold>
   700     // <editor-fold defaultstate="collapsed" desc="Contains Type">
   701     public boolean containedBy(Type t, Type s) {
   702         switch (t.tag) {
   703         case UNDETVAR:
   704             if (s.tag == WILDCARD) {
   705                 UndetVar undetvar = (UndetVar)t;
   707                 // Because of wildcard capture, s must be on the left
   708                 // hand side of an assignment.  Furthermore, t is an
   709                 // underconstrained type variable, for example, one
   710                 // that is only used in the return type of a method.
   711                 // If the type variable is truly underconstrained, it
   712                 // cannot have any low bounds:
   713                 assert undetvar.lobounds.isEmpty() : undetvar;
   715                 undetvar.inst = glb(upperBound(s), undetvar.inst);
   716                 return true;
   717             } else {
   718                 return isSameType(t, s);
   719             }
   720         case ERROR:
   721             return true;
   722         default:
   723             return containsType(s, t);
   724         }
   725     }
   727     boolean containsType(List<Type> ts, List<Type> ss) {
   728         while (ts.nonEmpty() && ss.nonEmpty()
   729                && containsType(ts.head, ss.head)) {
   730             ts = ts.tail;
   731             ss = ss.tail;
   732         }
   733         return ts.isEmpty() && ss.isEmpty();
   734     }
   736     /**
   737      * Check if t contains s.
   738      *
   739      * <p>T contains S if:
   740      *
   741      * <p>{@code L(T) <: L(S) && U(S) <: U(T)}
   742      *
   743      * <p>This relation is only used by ClassType.isSubtype(), that
   744      * is,
   745      *
   746      * <p>{@code C<S> <: C<T> if T contains S.}
   747      *
   748      * <p>Because of F-bounds, this relation can lead to infinite
   749      * recursion.  Thus we must somehow break that recursion.  Notice
   750      * that containsType() is only called from ClassType.isSubtype().
   751      * Since the arguments have already been checked against their
   752      * bounds, we know:
   753      *
   754      * <p>{@code U(S) <: U(T) if T is "super" bound (U(T) *is* the bound)}
   755      *
   756      * <p>{@code L(T) <: L(S) if T is "extends" bound (L(T) is bottom)}
   757      *
   758      * @param t a type
   759      * @param s a type
   760      */
   761     public boolean containsType(Type t, Type s) {
   762         return containsType.visit(t, s);
   763     }
   764     // where
   765         private TypeRelation containsType = new TypeRelation() {
   767             private Type U(Type t) {
   768                 while (t.tag == WILDCARD) {
   769                     WildcardType w = (WildcardType)t;
   770                     if (w.isSuperBound())
   771                         return w.bound == null ? syms.objectType : w.bound.bound;
   772                     else
   773                         t = w.type;
   774                 }
   775                 return t;
   776             }
   778             private Type L(Type t) {
   779                 while (t.tag == WILDCARD) {
   780                     WildcardType w = (WildcardType)t;
   781                     if (w.isExtendsBound())
   782                         return syms.botType;
   783                     else
   784                         t = w.type;
   785                 }
   786                 return t;
   787             }
   789             public Boolean visitType(Type t, Type s) {
   790                 if (s.tag >= firstPartialTag)
   791                     return containedBy(s, t);
   792                 else
   793                     return isSameType(t, s);
   794             }
   796             void debugContainsType(WildcardType t, Type s) {
   797                 System.err.println();
   798                 System.err.format(" does %s contain %s?%n", t, s);
   799                 System.err.format(" %s U(%s) <: U(%s) %s = %s%n",
   800                                   upperBound(s), s, t, U(t),
   801                                   t.isSuperBound()
   802                                   || isSubtypeNoCapture(upperBound(s), U(t)));
   803                 System.err.format(" %s L(%s) <: L(%s) %s = %s%n",
   804                                   L(t), t, s, lowerBound(s),
   805                                   t.isExtendsBound()
   806                                   || isSubtypeNoCapture(L(t), lowerBound(s)));
   807                 System.err.println();
   808             }
   810             @Override
   811             public Boolean visitWildcardType(WildcardType t, Type s) {
   812                 if (s.tag >= firstPartialTag)
   813                     return containedBy(s, t);
   814                 else {
   815                     // debugContainsType(t, s);
   816                     return isSameWildcard(t, s)
   817                         || isCaptureOf(s, t)
   818                         || ((t.isExtendsBound() || isSubtypeNoCapture(L(t), lowerBound(s))) &&
   819                             (t.isSuperBound() || isSubtypeNoCapture(upperBound(s), U(t))));
   820                 }
   821             }
   823             @Override
   824             public Boolean visitUndetVar(UndetVar t, Type s) {
   825                 if (s.tag != WILDCARD)
   826                     return isSameType(t, s);
   827                 else
   828                     return false;
   829             }
   831             @Override
   832             public Boolean visitErrorType(ErrorType t, Type s) {
   833                 return true;
   834             }
   835         };
   837     public boolean isCaptureOf(Type s, WildcardType t) {
   838         if (s.tag != TYPEVAR || !(s instanceof CapturedType))
   839             return false;
   840         return isSameWildcard(t, ((CapturedType)s).wildcard);
   841     }
   843     public boolean isSameWildcard(WildcardType t, Type s) {
   844         if (s.tag != WILDCARD)
   845             return false;
   846         WildcardType w = (WildcardType)s;
   847         return w.kind == t.kind && w.type == t.type;
   848     }
   850     public boolean containsTypeEquivalent(List<Type> ts, List<Type> ss) {
   851         while (ts.nonEmpty() && ss.nonEmpty()
   852                && containsTypeEquivalent(ts.head, ss.head)) {
   853             ts = ts.tail;
   854             ss = ss.tail;
   855         }
   856         return ts.isEmpty() && ss.isEmpty();
   857     }
   858     // </editor-fold>
   860     // <editor-fold defaultstate="collapsed" desc="isCastable">
   861     public boolean isCastable(Type t, Type s) {
   862         return isCastable(t, s, Warner.noWarnings);
   863     }
   865     /**
   866      * Is t is castable to s?<br>
   867      * s is assumed to be an erased type.<br>
   868      * (not defined for Method and ForAll types).
   869      */
   870     public boolean isCastable(Type t, Type s, Warner warn) {
   871         if (t == s)
   872             return true;
   874         if (t.isPrimitive() != s.isPrimitive())
   875             return allowBoxing && isConvertible(t, s, warn);
   877         if (warn != warnStack.head) {
   878             try {
   879                 warnStack = warnStack.prepend(warn);
   880                 return isCastable.visit(t, s);
   881             } finally {
   882                 warnStack = warnStack.tail;
   883             }
   884         } else {
   885             return isCastable.visit(t, s);
   886         }
   887     }
   888     // where
   889         private TypeRelation isCastable = new TypeRelation() {
   891             public Boolean visitType(Type t, Type s) {
   892                 if (s.tag == ERROR)
   893                     return true;
   895                 switch (t.tag) {
   896                 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
   897                 case DOUBLE:
   898                     return s.tag <= DOUBLE;
   899                 case BOOLEAN:
   900                     return s.tag == BOOLEAN;
   901                 case VOID:
   902                     return false;
   903                 case BOT:
   904                     return isSubtype(t, s);
   905                 default:
   906                     throw new AssertionError();
   907                 }
   908             }
   910             @Override
   911             public Boolean visitWildcardType(WildcardType t, Type s) {
   912                 return isCastable(upperBound(t), s, warnStack.head);
   913             }
   915             @Override
   916             public Boolean visitClassType(ClassType t, Type s) {
   917                 if (s.tag == ERROR || s.tag == BOT)
   918                     return true;
   920                 if (s.tag == TYPEVAR) {
   921                     if (isCastable(s.getUpperBound(), t, Warner.noWarnings)) {
   922                         warnStack.head.warnUnchecked();
   923                         return true;
   924                     } else {
   925                         return false;
   926                     }
   927                 }
   929                 if (t.isCompound()) {
   930                     if (!visit(supertype(t), s))
   931                         return false;
   932                     for (Type intf : interfaces(t)) {
   933                         if (!visit(intf, s))
   934                             return false;
   935                     }
   936                     return true;
   937                 }
   939                 if (s.isCompound()) {
   940                     // call recursively to reuse the above code
   941                     return visitClassType((ClassType)s, t);
   942                 }
   944                 if (s.tag == CLASS || s.tag == ARRAY) {
   945                     boolean upcast;
   946                     if ((upcast = isSubtype(erasure(t), erasure(s)))
   947                         || isSubtype(erasure(s), erasure(t))) {
   948                         if (!upcast && s.tag == ARRAY) {
   949                             if (!isReifiable(s))
   950                                 warnStack.head.warnUnchecked();
   951                             return true;
   952                         } else if (s.isRaw()) {
   953                             return true;
   954                         } else if (t.isRaw()) {
   955                             if (!isUnbounded(s))
   956                                 warnStack.head.warnUnchecked();
   957                             return true;
   958                         }
   959                         // Assume |a| <: |b|
   960                         final Type a = upcast ? t : s;
   961                         final Type b = upcast ? s : t;
   962                         final boolean HIGH = true;
   963                         final boolean LOW = false;
   964                         final boolean DONT_REWRITE_TYPEVARS = false;
   965                         Type aHigh = rewriteQuantifiers(a, HIGH, DONT_REWRITE_TYPEVARS);
   966                         Type aLow  = rewriteQuantifiers(a, LOW,  DONT_REWRITE_TYPEVARS);
   967                         Type bHigh = rewriteQuantifiers(b, HIGH, DONT_REWRITE_TYPEVARS);
   968                         Type bLow  = rewriteQuantifiers(b, LOW,  DONT_REWRITE_TYPEVARS);
   969                         Type lowSub = asSub(bLow, aLow.tsym);
   970                         Type highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym);
   971                         if (highSub == null) {
   972                             final boolean REWRITE_TYPEVARS = true;
   973                             aHigh = rewriteQuantifiers(a, HIGH, REWRITE_TYPEVARS);
   974                             aLow  = rewriteQuantifiers(a, LOW,  REWRITE_TYPEVARS);
   975                             bHigh = rewriteQuantifiers(b, HIGH, REWRITE_TYPEVARS);
   976                             bLow  = rewriteQuantifiers(b, LOW,  REWRITE_TYPEVARS);
   977                             lowSub = asSub(bLow, aLow.tsym);
   978                             highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym);
   979                         }
   980                         if (highSub != null) {
   981                             assert a.tsym == highSub.tsym && a.tsym == lowSub.tsym
   982                                 : a.tsym + " != " + highSub.tsym + " != " + lowSub.tsym;
   983                             if (!disjointTypes(aHigh.getTypeArguments(), highSub.getTypeArguments())
   984                                 && !disjointTypes(aHigh.getTypeArguments(), lowSub.getTypeArguments())
   985                                 && !disjointTypes(aLow.getTypeArguments(), highSub.getTypeArguments())
   986                                 && !disjointTypes(aLow.getTypeArguments(), lowSub.getTypeArguments())) {
   987                                 if (upcast ? giveWarning(a, highSub) || giveWarning(a, lowSub)
   988                                            : giveWarning(highSub, a) || giveWarning(lowSub, a))
   989                                     warnStack.head.warnUnchecked();
   990                                 return true;
   991                             }
   992                         }
   993                         if (isReifiable(s))
   994                             return isSubtypeUnchecked(a, b);
   995                         else
   996                             return isSubtypeUnchecked(a, b, warnStack.head);
   997                     }
   999                     // Sidecast
  1000                     if (s.tag == CLASS) {
  1001                         if ((s.tsym.flags() & INTERFACE) != 0) {
  1002                             return ((t.tsym.flags() & FINAL) == 0)
  1003                                 ? sideCast(t, s, warnStack.head)
  1004                                 : sideCastFinal(t, s, warnStack.head);
  1005                         } else if ((t.tsym.flags() & INTERFACE) != 0) {
  1006                             return ((s.tsym.flags() & FINAL) == 0)
  1007                                 ? sideCast(t, s, warnStack.head)
  1008                                 : sideCastFinal(t, s, warnStack.head);
  1009                         } else {
  1010                             // unrelated class types
  1011                             return false;
  1015                 return false;
  1018             @Override
  1019             public Boolean visitArrayType(ArrayType t, Type s) {
  1020                 switch (s.tag) {
  1021                 case ERROR:
  1022                 case BOT:
  1023                     return true;
  1024                 case TYPEVAR:
  1025                     if (isCastable(s, t, Warner.noWarnings)) {
  1026                         warnStack.head.warnUnchecked();
  1027                         return true;
  1028                     } else {
  1029                         return false;
  1031                 case CLASS:
  1032                     return isSubtype(t, s);
  1033                 case ARRAY:
  1034                     if (elemtype(t).tag <= lastBaseTag) {
  1035                         return elemtype(t).tag == elemtype(s).tag;
  1036                     } else {
  1037                         return visit(elemtype(t), elemtype(s));
  1039                 default:
  1040                     return false;
  1044             @Override
  1045             public Boolean visitTypeVar(TypeVar t, Type s) {
  1046                 switch (s.tag) {
  1047                 case ERROR:
  1048                 case BOT:
  1049                     return true;
  1050                 case TYPEVAR:
  1051                     if (isSubtype(t, s)) {
  1052                         return true;
  1053                     } else if (isCastable(t.bound, s, Warner.noWarnings)) {
  1054                         warnStack.head.warnUnchecked();
  1055                         return true;
  1056                     } else {
  1057                         return false;
  1059                 default:
  1060                     return isCastable(t.bound, s, warnStack.head);
  1064             @Override
  1065             public Boolean visitErrorType(ErrorType t, Type s) {
  1066                 return true;
  1068         };
  1069     // </editor-fold>
  1071     // <editor-fold defaultstate="collapsed" desc="disjointTypes">
  1072     public boolean disjointTypes(List<Type> ts, List<Type> ss) {
  1073         while (ts.tail != null && ss.tail != null) {
  1074             if (disjointType(ts.head, ss.head)) return true;
  1075             ts = ts.tail;
  1076             ss = ss.tail;
  1078         return false;
  1081     /**
  1082      * Two types or wildcards are considered disjoint if it can be
  1083      * proven that no type can be contained in both. It is
  1084      * conservative in that it is allowed to say that two types are
  1085      * not disjoint, even though they actually are.
  1087      * The type C<X> is castable to C<Y> exactly if X and Y are not
  1088      * disjoint.
  1089      */
  1090     public boolean disjointType(Type t, Type s) {
  1091         return disjointType.visit(t, s);
  1093     // where
  1094         private TypeRelation disjointType = new TypeRelation() {
  1096             private Set<TypePair> cache = new HashSet<TypePair>();
  1098             public Boolean visitType(Type t, Type s) {
  1099                 if (s.tag == WILDCARD)
  1100                     return visit(s, t);
  1101                 else
  1102                     return notSoftSubtypeRecursive(t, s) || notSoftSubtypeRecursive(s, t);
  1105             private boolean isCastableRecursive(Type t, Type s) {
  1106                 TypePair pair = new TypePair(t, s);
  1107                 if (cache.add(pair)) {
  1108                     try {
  1109                         return Types.this.isCastable(t, s);
  1110                     } finally {
  1111                         cache.remove(pair);
  1113                 } else {
  1114                     return true;
  1118             private boolean notSoftSubtypeRecursive(Type t, Type s) {
  1119                 TypePair pair = new TypePair(t, s);
  1120                 if (cache.add(pair)) {
  1121                     try {
  1122                         return Types.this.notSoftSubtype(t, s);
  1123                     } finally {
  1124                         cache.remove(pair);
  1126                 } else {
  1127                     return false;
  1131             @Override
  1132             public Boolean visitWildcardType(WildcardType t, Type s) {
  1133                 if (t.isUnbound())
  1134                     return false;
  1136                 if (s.tag != WILDCARD) {
  1137                     if (t.isExtendsBound())
  1138                         return notSoftSubtypeRecursive(s, t.type);
  1139                     else // isSuperBound()
  1140                         return notSoftSubtypeRecursive(t.type, s);
  1143                 if (s.isUnbound())
  1144                     return false;
  1146                 if (t.isExtendsBound()) {
  1147                     if (s.isExtendsBound())
  1148                         return !isCastableRecursive(t.type, upperBound(s));
  1149                     else if (s.isSuperBound())
  1150                         return notSoftSubtypeRecursive(lowerBound(s), t.type);
  1151                 } else if (t.isSuperBound()) {
  1152                     if (s.isExtendsBound())
  1153                         return notSoftSubtypeRecursive(t.type, upperBound(s));
  1155                 return false;
  1157         };
  1158     // </editor-fold>
  1160     // <editor-fold defaultstate="collapsed" desc="lowerBoundArgtypes">
  1161     /**
  1162      * Returns the lower bounds of the formals of a method.
  1163      */
  1164     public List<Type> lowerBoundArgtypes(Type t) {
  1165         return map(t.getParameterTypes(), lowerBoundMapping);
  1167     private final Mapping lowerBoundMapping = new Mapping("lowerBound") {
  1168             public Type apply(Type t) {
  1169                 return lowerBound(t);
  1171         };
  1172     // </editor-fold>
  1174     // <editor-fold defaultstate="collapsed" desc="notSoftSubtype">
  1175     /**
  1176      * This relation answers the question: is impossible that
  1177      * something of type `t' can be a subtype of `s'? This is
  1178      * different from the question "is `t' not a subtype of `s'?"
  1179      * when type variables are involved: Integer is not a subtype of T
  1180      * where <T extends Number> but it is not true that Integer cannot
  1181      * possibly be a subtype of T.
  1182      */
  1183     public boolean notSoftSubtype(Type t, Type s) {
  1184         if (t == s) return false;
  1185         if (t.tag == TYPEVAR) {
  1186             TypeVar tv = (TypeVar) t;
  1187             if (s.tag == TYPEVAR)
  1188                 s = s.getUpperBound();
  1189             return !isCastable(tv.bound,
  1190                                s,
  1191                                Warner.noWarnings);
  1193         if (s.tag != WILDCARD)
  1194             s = upperBound(s);
  1195         if (s.tag == TYPEVAR)
  1196             s = s.getUpperBound();
  1197         return !isSubtype(t, s);
  1199     // </editor-fold>
  1201     // <editor-fold defaultstate="collapsed" desc="isReifiable">
  1202     public boolean isReifiable(Type t) {
  1203         return isReifiable.visit(t);
  1205     // where
  1206         private UnaryVisitor<Boolean> isReifiable = new UnaryVisitor<Boolean>() {
  1208             public Boolean visitType(Type t, Void ignored) {
  1209                 return true;
  1212             @Override
  1213             public Boolean visitClassType(ClassType t, Void ignored) {
  1214                 if (!t.isParameterized())
  1215                     return true;
  1217                 for (Type param : t.allparams()) {
  1218                     if (!param.isUnbound())
  1219                         return false;
  1221                 return true;
  1224             @Override
  1225             public Boolean visitArrayType(ArrayType t, Void ignored) {
  1226                 return visit(t.elemtype);
  1229             @Override
  1230             public Boolean visitTypeVar(TypeVar t, Void ignored) {
  1231                 return false;
  1233         };
  1234     // </editor-fold>
  1236     // <editor-fold defaultstate="collapsed" desc="Array Utils">
  1237     public boolean isArray(Type t) {
  1238         while (t.tag == WILDCARD)
  1239             t = upperBound(t);
  1240         return t.tag == ARRAY;
  1243     /**
  1244      * The element type of an array.
  1245      */
  1246     public Type elemtype(Type t) {
  1247         switch (t.tag) {
  1248         case WILDCARD:
  1249             return elemtype(upperBound(t));
  1250         case ARRAY:
  1251             return ((ArrayType)t).elemtype;
  1252         case FORALL:
  1253             return elemtype(((ForAll)t).qtype);
  1254         case ERROR:
  1255             return t;
  1256         default:
  1257             return null;
  1261     /**
  1262      * Mapping to take element type of an arraytype
  1263      */
  1264     private Mapping elemTypeFun = new Mapping ("elemTypeFun") {
  1265         public Type apply(Type t) { return elemtype(t); }
  1266     };
  1268     /**
  1269      * The number of dimensions of an array type.
  1270      */
  1271     public int dimensions(Type t) {
  1272         int result = 0;
  1273         while (t.tag == ARRAY) {
  1274             result++;
  1275             t = elemtype(t);
  1277         return result;
  1279     // </editor-fold>
  1281     // <editor-fold defaultstate="collapsed" desc="asSuper">
  1282     /**
  1283      * Return the (most specific) base type of t that starts with the
  1284      * given symbol.  If none exists, return null.
  1286      * @param t a type
  1287      * @param sym a symbol
  1288      */
  1289     public Type asSuper(Type t, Symbol sym) {
  1290         return asSuper.visit(t, sym);
  1292     // where
  1293         private SimpleVisitor<Type,Symbol> asSuper = new SimpleVisitor<Type,Symbol>() {
  1295             public Type visitType(Type t, Symbol sym) {
  1296                 return null;
  1299             @Override
  1300             public Type visitClassType(ClassType t, Symbol sym) {
  1301                 if (t.tsym == sym)
  1302                     return t;
  1304                 Type st = supertype(t);
  1305                 if (st.tag == CLASS || st.tag == TYPEVAR || st.tag == ERROR) {
  1306                     Type x = asSuper(st, sym);
  1307                     if (x != null)
  1308                         return x;
  1310                 if ((sym.flags() & INTERFACE) != 0) {
  1311                     for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
  1312                         Type x = asSuper(l.head, sym);
  1313                         if (x != null)
  1314                             return x;
  1317                 return null;
  1320             @Override
  1321             public Type visitArrayType(ArrayType t, Symbol sym) {
  1322                 return isSubtype(t, sym.type) ? sym.type : null;
  1325             @Override
  1326             public Type visitTypeVar(TypeVar t, Symbol sym) {
  1327                 if (t.tsym == sym)
  1328                     return t;
  1329                 else
  1330                     return asSuper(t.bound, sym);
  1333             @Override
  1334             public Type visitErrorType(ErrorType t, Symbol sym) {
  1335                 return t;
  1337         };
  1339     /**
  1340      * Return the base type of t or any of its outer types that starts
  1341      * with the given symbol.  If none exists, return null.
  1343      * @param t a type
  1344      * @param sym a symbol
  1345      */
  1346     public Type asOuterSuper(Type t, Symbol sym) {
  1347         switch (t.tag) {
  1348         case CLASS:
  1349             do {
  1350                 Type s = asSuper(t, sym);
  1351                 if (s != null) return s;
  1352                 t = t.getEnclosingType();
  1353             } while (t.tag == CLASS);
  1354             return null;
  1355         case ARRAY:
  1356             return isSubtype(t, sym.type) ? sym.type : null;
  1357         case TYPEVAR:
  1358             return asSuper(t, sym);
  1359         case ERROR:
  1360             return t;
  1361         default:
  1362             return null;
  1366     /**
  1367      * Return the base type of t or any of its enclosing types that
  1368      * starts with the given symbol.  If none exists, return null.
  1370      * @param t a type
  1371      * @param sym a symbol
  1372      */
  1373     public Type asEnclosingSuper(Type t, Symbol sym) {
  1374         switch (t.tag) {
  1375         case CLASS:
  1376             do {
  1377                 Type s = asSuper(t, sym);
  1378                 if (s != null) return s;
  1379                 Type outer = t.getEnclosingType();
  1380                 t = (outer.tag == CLASS) ? outer :
  1381                     (t.tsym.owner.enclClass() != null) ? t.tsym.owner.enclClass().type :
  1382                     Type.noType;
  1383             } while (t.tag == CLASS);
  1384             return null;
  1385         case ARRAY:
  1386             return isSubtype(t, sym.type) ? sym.type : null;
  1387         case TYPEVAR:
  1388             return asSuper(t, sym);
  1389         case ERROR:
  1390             return t;
  1391         default:
  1392             return null;
  1395     // </editor-fold>
  1397     // <editor-fold defaultstate="collapsed" desc="memberType">
  1398     /**
  1399      * The type of given symbol, seen as a member of t.
  1401      * @param t a type
  1402      * @param sym a symbol
  1403      */
  1404     public Type memberType(Type t, Symbol sym) {
  1405         return (sym.flags() & STATIC) != 0
  1406             ? sym.type
  1407             : memberType.visit(t, sym);
  1409     // where
  1410         private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
  1412             public Type visitType(Type t, Symbol sym) {
  1413                 return sym.type;
  1416             @Override
  1417             public Type visitWildcardType(WildcardType t, Symbol sym) {
  1418                 return memberType(upperBound(t), sym);
  1421             @Override
  1422             public Type visitClassType(ClassType t, Symbol sym) {
  1423                 Symbol owner = sym.owner;
  1424                 long flags = sym.flags();
  1425                 if (((flags & STATIC) == 0) && owner.type.isParameterized()) {
  1426                     Type base = asOuterSuper(t, owner);
  1427                     if (base != null) {
  1428                         List<Type> ownerParams = owner.type.allparams();
  1429                         List<Type> baseParams = base.allparams();
  1430                         if (ownerParams.nonEmpty()) {
  1431                             if (baseParams.isEmpty()) {
  1432                                 // then base is a raw type
  1433                                 return erasure(sym.type);
  1434                             } else {
  1435                                 return subst(sym.type, ownerParams, baseParams);
  1440                 return sym.type;
  1443             @Override
  1444             public Type visitTypeVar(TypeVar t, Symbol sym) {
  1445                 return memberType(t.bound, sym);
  1448             @Override
  1449             public Type visitErrorType(ErrorType t, Symbol sym) {
  1450                 return t;
  1452         };
  1453     // </editor-fold>
  1455     // <editor-fold defaultstate="collapsed" desc="isAssignable">
  1456     public boolean isAssignable(Type t, Type s) {
  1457         return isAssignable(t, s, Warner.noWarnings);
  1460     /**
  1461      * Is t assignable to s?<br>
  1462      * Equivalent to subtype except for constant values and raw
  1463      * types.<br>
  1464      * (not defined for Method and ForAll types)
  1465      */
  1466     public boolean isAssignable(Type t, Type s, Warner warn) {
  1467         if (t.tag == ERROR)
  1468             return true;
  1469         if (t.tag <= INT && t.constValue() != null) {
  1470             int value = ((Number)t.constValue()).intValue();
  1471             switch (s.tag) {
  1472             case BYTE:
  1473                 if (Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE)
  1474                     return true;
  1475                 break;
  1476             case CHAR:
  1477                 if (Character.MIN_VALUE <= value && value <= Character.MAX_VALUE)
  1478                     return true;
  1479                 break;
  1480             case SHORT:
  1481                 if (Short.MIN_VALUE <= value && value <= Short.MAX_VALUE)
  1482                     return true;
  1483                 break;
  1484             case INT:
  1485                 return true;
  1486             case CLASS:
  1487                 switch (unboxedType(s).tag) {
  1488                 case BYTE:
  1489                 case CHAR:
  1490                 case SHORT:
  1491                     return isAssignable(t, unboxedType(s), warn);
  1493                 break;
  1496         return isConvertible(t, s, warn);
  1498     // </editor-fold>
  1500     // <editor-fold defaultstate="collapsed" desc="erasure">
  1501     /**
  1502      * The erasure of t {@code |t|} -- the type that results when all
  1503      * type parameters in t are deleted.
  1504      */
  1505     public Type erasure(Type t) {
  1506         return erasure(t, false);
  1508     //where
  1509     private Type erasure(Type t, boolean recurse) {
  1510         if (t.tag <= lastBaseTag)
  1511             return t; /* fast special case */
  1512         else
  1513             return erasure.visit(t, recurse);
  1515     // where
  1516         private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() {
  1517             public Type visitType(Type t, Boolean recurse) {
  1518                 if (t.tag <= lastBaseTag)
  1519                     return t; /*fast special case*/
  1520                 else
  1521                     return t.map(recurse ? erasureRecFun : erasureFun);
  1524             @Override
  1525             public Type visitWildcardType(WildcardType t, Boolean recurse) {
  1526                 return erasure(upperBound(t), recurse);
  1529             @Override
  1530             public Type visitClassType(ClassType t, Boolean recurse) {
  1531                 Type erased = t.tsym.erasure(Types.this);
  1532                 if (recurse) {
  1533                     erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym);
  1535                 return erased;
  1538             @Override
  1539             public Type visitTypeVar(TypeVar t, Boolean recurse) {
  1540                 return erasure(t.bound, recurse);
  1543             @Override
  1544             public Type visitErrorType(ErrorType t, Boolean recurse) {
  1545                 return t;
  1547         };
  1549     private Mapping erasureFun = new Mapping ("erasure") {
  1550             public Type apply(Type t) { return erasure(t); }
  1551         };
  1553     private Mapping erasureRecFun = new Mapping ("erasureRecursive") {
  1554         public Type apply(Type t) { return erasureRecursive(t); }
  1555     };
  1557     public List<Type> erasure(List<Type> ts) {
  1558         return Type.map(ts, erasureFun);
  1561     public Type erasureRecursive(Type t) {
  1562         return erasure(t, true);
  1565     public List<Type> erasureRecursive(List<Type> ts) {
  1566         return Type.map(ts, erasureRecFun);
  1568     // </editor-fold>
  1570     // <editor-fold defaultstate="collapsed" desc="makeCompoundType">
  1571     /**
  1572      * Make a compound type from non-empty list of types
  1574      * @param bounds            the types from which the compound type is formed
  1575      * @param supertype         is objectType if all bounds are interfaces,
  1576      *                          null otherwise.
  1577      */
  1578     public Type makeCompoundType(List<Type> bounds,
  1579                                  Type supertype) {
  1580         ClassSymbol bc =
  1581             new ClassSymbol(ABSTRACT|PUBLIC|SYNTHETIC|COMPOUND|ACYCLIC,
  1582                             Type.moreInfo
  1583                                 ? names.fromString(bounds.toString())
  1584                                 : names.empty,
  1585                             syms.noSymbol);
  1586         if (bounds.head.tag == TYPEVAR)
  1587             // error condition, recover
  1588             bc.erasure_field = syms.objectType;
  1589         else
  1590             bc.erasure_field = erasure(bounds.head);
  1591         bc.members_field = new Scope(bc);
  1592         ClassType bt = (ClassType)bc.type;
  1593         bt.allparams_field = List.nil();
  1594         if (supertype != null) {
  1595             bt.supertype_field = supertype;
  1596             bt.interfaces_field = bounds;
  1597         } else {
  1598             bt.supertype_field = bounds.head;
  1599             bt.interfaces_field = bounds.tail;
  1601         assert bt.supertype_field.tsym.completer != null
  1602             || !bt.supertype_field.isInterface()
  1603             : bt.supertype_field;
  1604         return bt;
  1607     /**
  1608      * Same as {@link #makeCompoundType(List,Type)}, except that the
  1609      * second parameter is computed directly. Note that this might
  1610      * cause a symbol completion.  Hence, this version of
  1611      * makeCompoundType may not be called during a classfile read.
  1612      */
  1613     public Type makeCompoundType(List<Type> bounds) {
  1614         Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ?
  1615             supertype(bounds.head) : null;
  1616         return makeCompoundType(bounds, supertype);
  1619     /**
  1620      * A convenience wrapper for {@link #makeCompoundType(List)}; the
  1621      * arguments are converted to a list and passed to the other
  1622      * method.  Note that this might cause a symbol completion.
  1623      * Hence, this version of makeCompoundType may not be called
  1624      * during a classfile read.
  1625      */
  1626     public Type makeCompoundType(Type bound1, Type bound2) {
  1627         return makeCompoundType(List.of(bound1, bound2));
  1629     // </editor-fold>
  1631     // <editor-fold defaultstate="collapsed" desc="supertype">
  1632     public Type supertype(Type t) {
  1633         return supertype.visit(t);
  1635     // where
  1636         private UnaryVisitor<Type> supertype = new UnaryVisitor<Type>() {
  1638             public Type visitType(Type t, Void ignored) {
  1639                 // A note on wildcards: there is no good way to
  1640                 // determine a supertype for a super bounded wildcard.
  1641                 return null;
  1644             @Override
  1645             public Type visitClassType(ClassType t, Void ignored) {
  1646                 if (t.supertype_field == null) {
  1647                     Type supertype = ((ClassSymbol)t.tsym).getSuperclass();
  1648                     // An interface has no superclass; its supertype is Object.
  1649                     if (t.isInterface())
  1650                         supertype = ((ClassType)t.tsym.type).supertype_field;
  1651                     if (t.supertype_field == null) {
  1652                         List<Type> actuals = classBound(t).allparams();
  1653                         List<Type> formals = t.tsym.type.allparams();
  1654                         if (t.hasErasedSupertypes()) {
  1655                             t.supertype_field = erasureRecursive(supertype);
  1656                         } else if (formals.nonEmpty()) {
  1657                             t.supertype_field = subst(supertype, formals, actuals);
  1659                         else {
  1660                             t.supertype_field = supertype;
  1664                 return t.supertype_field;
  1667             /**
  1668              * The supertype is always a class type. If the type
  1669              * variable's bounds start with a class type, this is also
  1670              * the supertype.  Otherwise, the supertype is
  1671              * java.lang.Object.
  1672              */
  1673             @Override
  1674             public Type visitTypeVar(TypeVar t, Void ignored) {
  1675                 if (t.bound.tag == TYPEVAR ||
  1676                     (!t.bound.isCompound() && !t.bound.isInterface())) {
  1677                     return t.bound;
  1678                 } else {
  1679                     return supertype(t.bound);
  1683             @Override
  1684             public Type visitArrayType(ArrayType t, Void ignored) {
  1685                 if (t.elemtype.isPrimitive() || isSameType(t.elemtype, syms.objectType))
  1686                     return arraySuperType();
  1687                 else
  1688                     return new ArrayType(supertype(t.elemtype), t.tsym);
  1691             @Override
  1692             public Type visitErrorType(ErrorType t, Void ignored) {
  1693                 return t;
  1695         };
  1696     // </editor-fold>
  1698     // <editor-fold defaultstate="collapsed" desc="interfaces">
  1699     /**
  1700      * Return the interfaces implemented by this class.
  1701      */
  1702     public List<Type> interfaces(Type t) {
  1703         return interfaces.visit(t);
  1705     // where
  1706         private UnaryVisitor<List<Type>> interfaces = new UnaryVisitor<List<Type>>() {
  1708             public List<Type> visitType(Type t, Void ignored) {
  1709                 return List.nil();
  1712             @Override
  1713             public List<Type> visitClassType(ClassType t, Void ignored) {
  1714                 if (t.interfaces_field == null) {
  1715                     List<Type> interfaces = ((ClassSymbol)t.tsym).getInterfaces();
  1716                     if (t.interfaces_field == null) {
  1717                         // If t.interfaces_field is null, then t must
  1718                         // be a parameterized type (not to be confused
  1719                         // with a generic type declaration).
  1720                         // Terminology:
  1721                         //    Parameterized type: List<String>
  1722                         //    Generic type declaration: class List<E> { ... }
  1723                         // So t corresponds to List<String> and
  1724                         // t.tsym.type corresponds to List<E>.
  1725                         // The reason t must be parameterized type is
  1726                         // that completion will happen as a side
  1727                         // effect of calling
  1728                         // ClassSymbol.getInterfaces.  Since
  1729                         // t.interfaces_field is null after
  1730                         // completion, we can assume that t is not the
  1731                         // type of a class/interface declaration.
  1732                         assert t != t.tsym.type : t.toString();
  1733                         List<Type> actuals = t.allparams();
  1734                         List<Type> formals = t.tsym.type.allparams();
  1735                         if (t.hasErasedSupertypes()) {
  1736                             t.interfaces_field = erasureRecursive(interfaces);
  1737                         } else if (formals.nonEmpty()) {
  1738                             t.interfaces_field =
  1739                                 upperBounds(subst(interfaces, formals, actuals));
  1741                         else {
  1742                             t.interfaces_field = interfaces;
  1746                 return t.interfaces_field;
  1749             @Override
  1750             public List<Type> visitTypeVar(TypeVar t, Void ignored) {
  1751                 if (t.bound.isCompound())
  1752                     return interfaces(t.bound);
  1754                 if (t.bound.isInterface())
  1755                     return List.of(t.bound);
  1757                 return List.nil();
  1759         };
  1760     // </editor-fold>
  1762     // <editor-fold defaultstate="collapsed" desc="isDerivedRaw">
  1763     Map<Type,Boolean> isDerivedRawCache = new HashMap<Type,Boolean>();
  1765     public boolean isDerivedRaw(Type t) {
  1766         Boolean result = isDerivedRawCache.get(t);
  1767         if (result == null) {
  1768             result = isDerivedRawInternal(t);
  1769             isDerivedRawCache.put(t, result);
  1771         return result;
  1774     public boolean isDerivedRawInternal(Type t) {
  1775         if (t.isErroneous())
  1776             return false;
  1777         return
  1778             t.isRaw() ||
  1779             supertype(t) != null && isDerivedRaw(supertype(t)) ||
  1780             isDerivedRaw(interfaces(t));
  1783     public boolean isDerivedRaw(List<Type> ts) {
  1784         List<Type> l = ts;
  1785         while (l.nonEmpty() && !isDerivedRaw(l.head)) l = l.tail;
  1786         return l.nonEmpty();
  1788     // </editor-fold>
  1790     // <editor-fold defaultstate="collapsed" desc="setBounds">
  1791     /**
  1792      * Set the bounds field of the given type variable to reflect a
  1793      * (possibly multiple) list of bounds.
  1794      * @param t                 a type variable
  1795      * @param bounds            the bounds, must be nonempty
  1796      * @param supertype         is objectType if all bounds are interfaces,
  1797      *                          null otherwise.
  1798      */
  1799     public void setBounds(TypeVar t, List<Type> bounds, Type supertype) {
  1800         if (bounds.tail.isEmpty())
  1801             t.bound = bounds.head;
  1802         else
  1803             t.bound = makeCompoundType(bounds, supertype);
  1804         t.rank_field = -1;
  1807     /**
  1808      * Same as {@link #setBounds(Type.TypeVar,List,Type)}, except that
  1809      * third parameter is computed directly.  Note that this test
  1810      * might cause a symbol completion.  Hence, this version of
  1811      * setBounds may not be called during a classfile read.
  1812      */
  1813     public void setBounds(TypeVar t, List<Type> bounds) {
  1814         Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ?
  1815             supertype(bounds.head) : null;
  1816         setBounds(t, bounds, supertype);
  1817         t.rank_field = -1;
  1819     // </editor-fold>
  1821     // <editor-fold defaultstate="collapsed" desc="getBounds">
  1822     /**
  1823      * Return list of bounds of the given type variable.
  1824      */
  1825     public List<Type> getBounds(TypeVar t) {
  1826         if (t.bound.isErroneous() || !t.bound.isCompound())
  1827             return List.of(t.bound);
  1828         else if ((erasure(t).tsym.flags() & INTERFACE) == 0)
  1829             return interfaces(t).prepend(supertype(t));
  1830         else
  1831             // No superclass was given in bounds.
  1832             // In this case, supertype is Object, erasure is first interface.
  1833             return interfaces(t);
  1835     // </editor-fold>
  1837     // <editor-fold defaultstate="collapsed" desc="classBound">
  1838     /**
  1839      * If the given type is a (possibly selected) type variable,
  1840      * return the bounding class of this type, otherwise return the
  1841      * type itself.
  1842      */
  1843     public Type classBound(Type t) {
  1844         return classBound.visit(t);
  1846     // where
  1847         private UnaryVisitor<Type> classBound = new UnaryVisitor<Type>() {
  1849             public Type visitType(Type t, Void ignored) {
  1850                 return t;
  1853             @Override
  1854             public Type visitClassType(ClassType t, Void ignored) {
  1855                 Type outer1 = classBound(t.getEnclosingType());
  1856                 if (outer1 != t.getEnclosingType())
  1857                     return new ClassType(outer1, t.getTypeArguments(), t.tsym);
  1858                 else
  1859                     return t;
  1862             @Override
  1863             public Type visitTypeVar(TypeVar t, Void ignored) {
  1864                 return classBound(supertype(t));
  1867             @Override
  1868             public Type visitErrorType(ErrorType t, Void ignored) {
  1869                 return t;
  1871         };
  1872     // </editor-fold>
  1874     // <editor-fold defaultstate="collapsed" desc="sub signature / override equivalence">
  1875     /**
  1876      * Returns true iff the first signature is a <em>sub
  1877      * signature</em> of the other.  This is <b>not</b> an equivalence
  1878      * relation.
  1880      * @see "The Java Language Specification, Third Ed. (8.4.2)."
  1881      * @see #overrideEquivalent(Type t, Type s)
  1882      * @param t first signature (possibly raw).
  1883      * @param s second signature (could be subjected to erasure).
  1884      * @return true if t is a sub signature of s.
  1885      */
  1886     public boolean isSubSignature(Type t, Type s) {
  1887         return hasSameArgs(t, s) || hasSameArgs(t, erasure(s));
  1890     /**
  1891      * Returns true iff these signatures are related by <em>override
  1892      * equivalence</em>.  This is the natural extension of
  1893      * isSubSignature to an equivalence relation.
  1895      * @see "The Java Language Specification, Third Ed. (8.4.2)."
  1896      * @see #isSubSignature(Type t, Type s)
  1897      * @param t a signature (possible raw, could be subjected to
  1898      * erasure).
  1899      * @param s a signature (possible raw, could be subjected to
  1900      * erasure).
  1901      * @return true if either argument is a sub signature of the other.
  1902      */
  1903     public boolean overrideEquivalent(Type t, Type s) {
  1904         return hasSameArgs(t, s) ||
  1905             hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s);
  1908     /**
  1909      * Does t have the same arguments as s?  It is assumed that both
  1910      * types are (possibly polymorphic) method types.  Monomorphic
  1911      * method types "have the same arguments", if their argument lists
  1912      * are equal.  Polymorphic method types "have the same arguments",
  1913      * if they have the same arguments after renaming all type
  1914      * variables of one to corresponding type variables in the other,
  1915      * where correspondence is by position in the type parameter list.
  1916      */
  1917     public boolean hasSameArgs(Type t, Type s) {
  1918         return hasSameArgs.visit(t, s);
  1920     // where
  1921         private TypeRelation hasSameArgs = new TypeRelation() {
  1923             public Boolean visitType(Type t, Type s) {
  1924                 throw new AssertionError();
  1927             @Override
  1928             public Boolean visitMethodType(MethodType t, Type s) {
  1929                 return s.tag == METHOD
  1930                     && containsTypeEquivalent(t.argtypes, s.getParameterTypes());
  1933             @Override
  1934             public Boolean visitForAll(ForAll t, Type s) {
  1935                 if (s.tag != FORALL)
  1936                     return false;
  1938                 ForAll forAll = (ForAll)s;
  1939                 return hasSameBounds(t, forAll)
  1940                     && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
  1943             @Override
  1944             public Boolean visitErrorType(ErrorType t, Type s) {
  1945                 return false;
  1947         };
  1948     // </editor-fold>
  1950     // <editor-fold defaultstate="collapsed" desc="subst">
  1951     public List<Type> subst(List<Type> ts,
  1952                             List<Type> from,
  1953                             List<Type> to) {
  1954         return new Subst(from, to).subst(ts);
  1957     /**
  1958      * Substitute all occurrences of a type in `from' with the
  1959      * corresponding type in `to' in 't'. Match lists `from' and `to'
  1960      * from the right: If lists have different length, discard leading
  1961      * elements of the longer list.
  1962      */
  1963     public Type subst(Type t, List<Type> from, List<Type> to) {
  1964         return new Subst(from, to).subst(t);
  1967     private class Subst extends UnaryVisitor<Type> {
  1968         List<Type> from;
  1969         List<Type> to;
  1971         public Subst(List<Type> from, List<Type> to) {
  1972             int fromLength = from.length();
  1973             int toLength = to.length();
  1974             while (fromLength > toLength) {
  1975                 fromLength--;
  1976                 from = from.tail;
  1978             while (fromLength < toLength) {
  1979                 toLength--;
  1980                 to = to.tail;
  1982             this.from = from;
  1983             this.to = to;
  1986         Type subst(Type t) {
  1987             if (from.tail == null)
  1988                 return t;
  1989             else
  1990                 return visit(t);
  1993         List<Type> subst(List<Type> ts) {
  1994             if (from.tail == null)
  1995                 return ts;
  1996             boolean wild = false;
  1997             if (ts.nonEmpty() && from.nonEmpty()) {
  1998                 Type head1 = subst(ts.head);
  1999                 List<Type> tail1 = subst(ts.tail);
  2000                 if (head1 != ts.head || tail1 != ts.tail)
  2001                     return tail1.prepend(head1);
  2003             return ts;
  2006         public Type visitType(Type t, Void ignored) {
  2007             return t;
  2010         @Override
  2011         public Type visitMethodType(MethodType t, Void ignored) {
  2012             List<Type> argtypes = subst(t.argtypes);
  2013             Type restype = subst(t.restype);
  2014             List<Type> thrown = subst(t.thrown);
  2015             if (argtypes == t.argtypes &&
  2016                 restype == t.restype &&
  2017                 thrown == t.thrown)
  2018                 return t;
  2019             else
  2020                 return new MethodType(argtypes, restype, thrown, t.tsym);
  2023         @Override
  2024         public Type visitTypeVar(TypeVar t, Void ignored) {
  2025             for (List<Type> from = this.from, to = this.to;
  2026                  from.nonEmpty();
  2027                  from = from.tail, to = to.tail) {
  2028                 if (t == from.head) {
  2029                     return to.head.withTypeVar(t);
  2032             return t;
  2035         @Override
  2036         public Type visitClassType(ClassType t, Void ignored) {
  2037             if (!t.isCompound()) {
  2038                 List<Type> typarams = t.getTypeArguments();
  2039                 List<Type> typarams1 = subst(typarams);
  2040                 Type outer = t.getEnclosingType();
  2041                 Type outer1 = subst(outer);
  2042                 if (typarams1 == typarams && outer1 == outer)
  2043                     return t;
  2044                 else
  2045                     return new ClassType(outer1, typarams1, t.tsym);
  2046             } else {
  2047                 Type st = subst(supertype(t));
  2048                 List<Type> is = upperBounds(subst(interfaces(t)));
  2049                 if (st == supertype(t) && is == interfaces(t))
  2050                     return t;
  2051                 else
  2052                     return makeCompoundType(is.prepend(st));
  2056         @Override
  2057         public Type visitWildcardType(WildcardType t, Void ignored) {
  2058             Type bound = t.type;
  2059             if (t.kind != BoundKind.UNBOUND)
  2060                 bound = subst(bound);
  2061             if (bound == t.type) {
  2062                 return t;
  2063             } else {
  2064                 if (t.isExtendsBound() && bound.isExtendsBound())
  2065                     bound = upperBound(bound);
  2066                 return new WildcardType(bound, t.kind, syms.boundClass, t.bound);
  2070         @Override
  2071         public Type visitArrayType(ArrayType t, Void ignored) {
  2072             Type elemtype = subst(t.elemtype);
  2073             if (elemtype == t.elemtype)
  2074                 return t;
  2075             else
  2076                 return new ArrayType(upperBound(elemtype), t.tsym);
  2079         @Override
  2080         public Type visitForAll(ForAll t, Void ignored) {
  2081             List<Type> tvars1 = substBounds(t.tvars, from, to);
  2082             Type qtype1 = subst(t.qtype);
  2083             if (tvars1 == t.tvars && qtype1 == t.qtype) {
  2084                 return t;
  2085             } else if (tvars1 == t.tvars) {
  2086                 return new ForAll(tvars1, qtype1);
  2087             } else {
  2088                 return new ForAll(tvars1, Types.this.subst(qtype1, t.tvars, tvars1));
  2092         @Override
  2093         public Type visitErrorType(ErrorType t, Void ignored) {
  2094             return t;
  2098     public List<Type> substBounds(List<Type> tvars,
  2099                                   List<Type> from,
  2100                                   List<Type> to) {
  2101         if (tvars.isEmpty())
  2102             return tvars;
  2103         if (tvars.tail.isEmpty())
  2104             // fast common case
  2105             return List.<Type>of(substBound((TypeVar)tvars.head, from, to));
  2106         ListBuffer<Type> newBoundsBuf = lb();
  2107         boolean changed = false;
  2108         // calculate new bounds
  2109         for (Type t : tvars) {
  2110             TypeVar tv = (TypeVar) t;
  2111             Type bound = subst(tv.bound, from, to);
  2112             if (bound != tv.bound)
  2113                 changed = true;
  2114             newBoundsBuf.append(bound);
  2116         if (!changed)
  2117             return tvars;
  2118         ListBuffer<Type> newTvars = lb();
  2119         // create new type variables without bounds
  2120         for (Type t : tvars) {
  2121             newTvars.append(new TypeVar(t.tsym, null, syms.botType));
  2123         // the new bounds should use the new type variables in place
  2124         // of the old
  2125         List<Type> newBounds = newBoundsBuf.toList();
  2126         from = tvars;
  2127         to = newTvars.toList();
  2128         for (; !newBounds.isEmpty(); newBounds = newBounds.tail) {
  2129             newBounds.head = subst(newBounds.head, from, to);
  2131         newBounds = newBoundsBuf.toList();
  2132         // set the bounds of new type variables to the new bounds
  2133         for (Type t : newTvars.toList()) {
  2134             TypeVar tv = (TypeVar) t;
  2135             tv.bound = newBounds.head;
  2136             newBounds = newBounds.tail;
  2138         return newTvars.toList();
  2141     public TypeVar substBound(TypeVar t, List<Type> from, List<Type> to) {
  2142         Type bound1 = subst(t.bound, from, to);
  2143         if (bound1 == t.bound)
  2144             return t;
  2145         else
  2146             return new TypeVar(t.tsym, bound1, syms.botType);
  2148     // </editor-fold>
  2150     // <editor-fold defaultstate="collapsed" desc="hasSameBounds">
  2151     /**
  2152      * Does t have the same bounds for quantified variables as s?
  2153      */
  2154     boolean hasSameBounds(ForAll t, ForAll s) {
  2155         List<Type> l1 = t.tvars;
  2156         List<Type> l2 = s.tvars;
  2157         while (l1.nonEmpty() && l2.nonEmpty() &&
  2158                isSameType(l1.head.getUpperBound(),
  2159                           subst(l2.head.getUpperBound(),
  2160                                 s.tvars,
  2161                                 t.tvars))) {
  2162             l1 = l1.tail;
  2163             l2 = l2.tail;
  2165         return l1.isEmpty() && l2.isEmpty();
  2167     // </editor-fold>
  2169     // <editor-fold defaultstate="collapsed" desc="newInstances">
  2170     /** Create new vector of type variables from list of variables
  2171      *  changing all recursive bounds from old to new list.
  2172      */
  2173     public List<Type> newInstances(List<Type> tvars) {
  2174         List<Type> tvars1 = Type.map(tvars, newInstanceFun);
  2175         for (List<Type> l = tvars1; l.nonEmpty(); l = l.tail) {
  2176             TypeVar tv = (TypeVar) l.head;
  2177             tv.bound = subst(tv.bound, tvars, tvars1);
  2179         return tvars1;
  2181     static private Mapping newInstanceFun = new Mapping("newInstanceFun") {
  2182             public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound()); }
  2183         };
  2184     // </editor-fold>
  2186     // <editor-fold defaultstate="collapsed" desc="rank">
  2187     /**
  2188      * The rank of a class is the length of the longest path between
  2189      * the class and java.lang.Object in the class inheritance
  2190      * graph. Undefined for all but reference types.
  2191      */
  2192     public int rank(Type t) {
  2193         switch(t.tag) {
  2194         case CLASS: {
  2195             ClassType cls = (ClassType)t;
  2196             if (cls.rank_field < 0) {
  2197                 Name fullname = cls.tsym.getQualifiedName();
  2198                 if (fullname == fullname.table.java_lang_Object)
  2199                     cls.rank_field = 0;
  2200                 else {
  2201                     int r = rank(supertype(cls));
  2202                     for (List<Type> l = interfaces(cls);
  2203                          l.nonEmpty();
  2204                          l = l.tail) {
  2205                         if (rank(l.head) > r)
  2206                             r = rank(l.head);
  2208                     cls.rank_field = r + 1;
  2211             return cls.rank_field;
  2213         case TYPEVAR: {
  2214             TypeVar tvar = (TypeVar)t;
  2215             if (tvar.rank_field < 0) {
  2216                 int r = rank(supertype(tvar));
  2217                 for (List<Type> l = interfaces(tvar);
  2218                      l.nonEmpty();
  2219                      l = l.tail) {
  2220                     if (rank(l.head) > r) r = rank(l.head);
  2222                 tvar.rank_field = r + 1;
  2224             return tvar.rank_field;
  2226         case ERROR:
  2227             return 0;
  2228         default:
  2229             throw new AssertionError();
  2232     // </editor-fold>
  2234     // <editor-fold defaultstate="collapsed" desc="toString">
  2235     /**
  2236      * This toString is slightly more descriptive than the one on Type.
  2237      */
  2238     public String toString(Type t) {
  2239         if (t.tag == FORALL) {
  2240             ForAll forAll = (ForAll)t;
  2241             return typaramsString(forAll.tvars) + forAll.qtype;
  2243         return "" + t;
  2245     // where
  2246         private String typaramsString(List<Type> tvars) {
  2247             StringBuffer s = new StringBuffer();
  2248             s.append('<');
  2249             boolean first = true;
  2250             for (Type t : tvars) {
  2251                 if (!first) s.append(", ");
  2252                 first = false;
  2253                 appendTyparamString(((TypeVar)t), s);
  2255             s.append('>');
  2256             return s.toString();
  2258         private void appendTyparamString(TypeVar t, StringBuffer buf) {
  2259             buf.append(t);
  2260             if (t.bound == null ||
  2261                 t.bound.tsym.getQualifiedName() == names.java_lang_Object)
  2262                 return;
  2263             buf.append(" extends "); // Java syntax; no need for i18n
  2264             Type bound = t.bound;
  2265             if (!bound.isCompound()) {
  2266                 buf.append(bound);
  2267             } else if ((erasure(t).tsym.flags() & INTERFACE) == 0) {
  2268                 buf.append(supertype(t));
  2269                 for (Type intf : interfaces(t)) {
  2270                     buf.append('&');
  2271                     buf.append(intf);
  2273             } else {
  2274                 // No superclass was given in bounds.
  2275                 // In this case, supertype is Object, erasure is first interface.
  2276                 boolean first = true;
  2277                 for (Type intf : interfaces(t)) {
  2278                     if (!first) buf.append('&');
  2279                     first = false;
  2280                     buf.append(intf);
  2284     // </editor-fold>
  2286     // <editor-fold defaultstate="collapsed" desc="Determining least upper bounds of types">
  2287     /**
  2288      * A cache for closures.
  2290      * <p>A closure is a list of all the supertypes and interfaces of
  2291      * a class or interface type, ordered by ClassSymbol.precedes
  2292      * (that is, subclasses come first, arbitrary but fixed
  2293      * otherwise).
  2294      */
  2295     private Map<Type,List<Type>> closureCache = new HashMap<Type,List<Type>>();
  2297     /**
  2298      * Returns the closure of a class or interface type.
  2299      */
  2300     public List<Type> closure(Type t) {
  2301         List<Type> cl = closureCache.get(t);
  2302         if (cl == null) {
  2303             Type st = supertype(t);
  2304             if (!t.isCompound()) {
  2305                 if (st.tag == CLASS) {
  2306                     cl = insert(closure(st), t);
  2307                 } else if (st.tag == TYPEVAR) {
  2308                     cl = closure(st).prepend(t);
  2309                 } else {
  2310                     cl = List.of(t);
  2312             } else {
  2313                 cl = closure(supertype(t));
  2315             for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail)
  2316                 cl = union(cl, closure(l.head));
  2317             closureCache.put(t, cl);
  2319         return cl;
  2322     /**
  2323      * Insert a type in a closure
  2324      */
  2325     public List<Type> insert(List<Type> cl, Type t) {
  2326         if (cl.isEmpty() || t.tsym.precedes(cl.head.tsym, this)) {
  2327             return cl.prepend(t);
  2328         } else if (cl.head.tsym.precedes(t.tsym, this)) {
  2329             return insert(cl.tail, t).prepend(cl.head);
  2330         } else {
  2331             return cl;
  2335     /**
  2336      * Form the union of two closures
  2337      */
  2338     public List<Type> union(List<Type> cl1, List<Type> cl2) {
  2339         if (cl1.isEmpty()) {
  2340             return cl2;
  2341         } else if (cl2.isEmpty()) {
  2342             return cl1;
  2343         } else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) {
  2344             return union(cl1.tail, cl2).prepend(cl1.head);
  2345         } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) {
  2346             return union(cl1, cl2.tail).prepend(cl2.head);
  2347         } else {
  2348             return union(cl1.tail, cl2.tail).prepend(cl1.head);
  2352     /**
  2353      * Intersect two closures
  2354      */
  2355     public List<Type> intersect(List<Type> cl1, List<Type> cl2) {
  2356         if (cl1 == cl2)
  2357             return cl1;
  2358         if (cl1.isEmpty() || cl2.isEmpty())
  2359             return List.nil();
  2360         if (cl1.head.tsym.precedes(cl2.head.tsym, this))
  2361             return intersect(cl1.tail, cl2);
  2362         if (cl2.head.tsym.precedes(cl1.head.tsym, this))
  2363             return intersect(cl1, cl2.tail);
  2364         if (isSameType(cl1.head, cl2.head))
  2365             return intersect(cl1.tail, cl2.tail).prepend(cl1.head);
  2366         if (cl1.head.tsym == cl2.head.tsym &&
  2367             cl1.head.tag == CLASS && cl2.head.tag == CLASS) {
  2368             if (cl1.head.isParameterized() && cl2.head.isParameterized()) {
  2369                 Type merge = merge(cl1.head,cl2.head);
  2370                 return intersect(cl1.tail, cl2.tail).prepend(merge);
  2372             if (cl1.head.isRaw() || cl2.head.isRaw())
  2373                 return intersect(cl1.tail, cl2.tail).prepend(erasure(cl1.head));
  2375         return intersect(cl1.tail, cl2.tail);
  2377     // where
  2378         class TypePair {
  2379             final Type t1;
  2380             final Type t2;
  2381             TypePair(Type t1, Type t2) {
  2382                 this.t1 = t1;
  2383                 this.t2 = t2;
  2385             @Override
  2386             public int hashCode() {
  2387                 return 127 * Types.this.hashCode(t1) + Types.this.hashCode(t2);
  2389             @Override
  2390             public boolean equals(Object obj) {
  2391                 if (!(obj instanceof TypePair))
  2392                     return false;
  2393                 TypePair typePair = (TypePair)obj;
  2394                 return isSameType(t1, typePair.t1)
  2395                     && isSameType(t2, typePair.t2);
  2398         Set<TypePair> mergeCache = new HashSet<TypePair>();
  2399         private Type merge(Type c1, Type c2) {
  2400             ClassType class1 = (ClassType) c1;
  2401             List<Type> act1 = class1.getTypeArguments();
  2402             ClassType class2 = (ClassType) c2;
  2403             List<Type> act2 = class2.getTypeArguments();
  2404             ListBuffer<Type> merged = new ListBuffer<Type>();
  2405             List<Type> typarams = class1.tsym.type.getTypeArguments();
  2407             while (act1.nonEmpty() && act2.nonEmpty() && typarams.nonEmpty()) {
  2408                 if (containsType(act1.head, act2.head)) {
  2409                     merged.append(act1.head);
  2410                 } else if (containsType(act2.head, act1.head)) {
  2411                     merged.append(act2.head);
  2412                 } else {
  2413                     TypePair pair = new TypePair(c1, c2);
  2414                     Type m;
  2415                     if (mergeCache.add(pair)) {
  2416                         m = new WildcardType(lub(upperBound(act1.head),
  2417                                                  upperBound(act2.head)),
  2418                                              BoundKind.EXTENDS,
  2419                                              syms.boundClass);
  2420                         mergeCache.remove(pair);
  2421                     } else {
  2422                         m = new WildcardType(syms.objectType,
  2423                                              BoundKind.UNBOUND,
  2424                                              syms.boundClass);
  2426                     merged.append(m.withTypeVar(typarams.head));
  2428                 act1 = act1.tail;
  2429                 act2 = act2.tail;
  2430                 typarams = typarams.tail;
  2432             assert(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
  2433             return new ClassType(class1.getEnclosingType(), merged.toList(), class1.tsym);
  2436     /**
  2437      * Return the minimum type of a closure, a compound type if no
  2438      * unique minimum exists.
  2439      */
  2440     private Type compoundMin(List<Type> cl) {
  2441         if (cl.isEmpty()) return syms.objectType;
  2442         List<Type> compound = closureMin(cl);
  2443         if (compound.isEmpty())
  2444             return null;
  2445         else if (compound.tail.isEmpty())
  2446             return compound.head;
  2447         else
  2448             return makeCompoundType(compound);
  2451     /**
  2452      * Return the minimum types of a closure, suitable for computing
  2453      * compoundMin or glb.
  2454      */
  2455     private List<Type> closureMin(List<Type> cl) {
  2456         ListBuffer<Type> classes = lb();
  2457         ListBuffer<Type> interfaces = lb();
  2458         while (!cl.isEmpty()) {
  2459             Type current = cl.head;
  2460             if (current.isInterface())
  2461                 interfaces.append(current);
  2462             else
  2463                 classes.append(current);
  2464             ListBuffer<Type> candidates = lb();
  2465             for (Type t : cl.tail) {
  2466                 if (!isSubtypeNoCapture(current, t))
  2467                     candidates.append(t);
  2469             cl = candidates.toList();
  2471         return classes.appendList(interfaces).toList();
  2474     /**
  2475      * Return the least upper bound of pair of types.  if the lub does
  2476      * not exist return null.
  2477      */
  2478     public Type lub(Type t1, Type t2) {
  2479         return lub(List.of(t1, t2));
  2482     /**
  2483      * Return the least upper bound (lub) of set of types.  If the lub
  2484      * does not exist return the type of null (bottom).
  2485      */
  2486     public Type lub(List<Type> ts) {
  2487         final int ARRAY_BOUND = 1;
  2488         final int CLASS_BOUND = 2;
  2489         int boundkind = 0;
  2490         for (Type t : ts) {
  2491             switch (t.tag) {
  2492             case CLASS:
  2493                 boundkind |= CLASS_BOUND;
  2494                 break;
  2495             case ARRAY:
  2496                 boundkind |= ARRAY_BOUND;
  2497                 break;
  2498             case  TYPEVAR:
  2499                 do {
  2500                     t = t.getUpperBound();
  2501                 } while (t.tag == TYPEVAR);
  2502                 if (t.tag == ARRAY) {
  2503                     boundkind |= ARRAY_BOUND;
  2504                 } else {
  2505                     boundkind |= CLASS_BOUND;
  2507                 break;
  2508             default:
  2509                 if (t.isPrimitive())
  2510                     return syms.errType;
  2513         switch (boundkind) {
  2514         case 0:
  2515             return syms.botType;
  2517         case ARRAY_BOUND:
  2518             // calculate lub(A[], B[])
  2519             List<Type> elements = Type.map(ts, elemTypeFun);
  2520             for (Type t : elements) {
  2521                 if (t.isPrimitive()) {
  2522                     // if a primitive type is found, then return
  2523                     // arraySuperType unless all the types are the
  2524                     // same
  2525                     Type first = ts.head;
  2526                     for (Type s : ts.tail) {
  2527                         if (!isSameType(first, s)) {
  2528                              // lub(int[], B[]) is Cloneable & Serializable
  2529                             return arraySuperType();
  2532                     // all the array types are the same, return one
  2533                     // lub(int[], int[]) is int[]
  2534                     return first;
  2537             // lub(A[], B[]) is lub(A, B)[]
  2538             return new ArrayType(lub(elements), syms.arrayClass);
  2540         case CLASS_BOUND:
  2541             // calculate lub(A, B)
  2542             while (ts.head.tag != CLASS && ts.head.tag != TYPEVAR)
  2543                 ts = ts.tail;
  2544             assert !ts.isEmpty();
  2545             List<Type> cl = closure(ts.head);
  2546             for (Type t : ts.tail) {
  2547                 if (t.tag == CLASS || t.tag == TYPEVAR)
  2548                     cl = intersect(cl, closure(t));
  2550             return compoundMin(cl);
  2552         default:
  2553             // calculate lub(A, B[])
  2554             List<Type> classes = List.of(arraySuperType());
  2555             for (Type t : ts) {
  2556                 if (t.tag != ARRAY) // Filter out any arrays
  2557                     classes = classes.prepend(t);
  2559             // lub(A, B[]) is lub(A, arraySuperType)
  2560             return lub(classes);
  2563     // where
  2564         private Type arraySuperType = null;
  2565         private Type arraySuperType() {
  2566             // initialized lazily to avoid problems during compiler startup
  2567             if (arraySuperType == null) {
  2568                 synchronized (this) {
  2569                     if (arraySuperType == null) {
  2570                         // JLS 10.8: all arrays implement Cloneable and Serializable.
  2571                         arraySuperType = makeCompoundType(List.of(syms.serializableType,
  2572                                                                   syms.cloneableType),
  2573                                                           syms.objectType);
  2577             return arraySuperType;
  2579     // </editor-fold>
  2581     // <editor-fold defaultstate="collapsed" desc="Greatest lower bound">
  2582     public Type glb(Type t, Type s) {
  2583         if (s == null)
  2584             return t;
  2585         else if (isSubtypeNoCapture(t, s))
  2586             return t;
  2587         else if (isSubtypeNoCapture(s, t))
  2588             return s;
  2590         List<Type> closure = union(closure(t), closure(s));
  2591         List<Type> bounds = closureMin(closure);
  2593         if (bounds.isEmpty()) {             // length == 0
  2594             return syms.objectType;
  2595         } else if (bounds.tail.isEmpty()) { // length == 1
  2596             return bounds.head;
  2597         } else {                            // length > 1
  2598             int classCount = 0;
  2599             for (Type bound : bounds)
  2600                 if (!bound.isInterface())
  2601                     classCount++;
  2602             if (classCount > 1)
  2603                 return syms.errType;
  2605         return makeCompoundType(bounds);
  2607     // </editor-fold>
  2609     // <editor-fold defaultstate="collapsed" desc="hashCode">
  2610     /**
  2611      * Compute a hash code on a type.
  2612      */
  2613     public static int hashCode(Type t) {
  2614         return hashCode.visit(t);
  2616     // where
  2617         private static final UnaryVisitor<Integer> hashCode = new UnaryVisitor<Integer>() {
  2619             public Integer visitType(Type t, Void ignored) {
  2620                 return t.tag;
  2623             @Override
  2624             public Integer visitClassType(ClassType t, Void ignored) {
  2625                 int result = visit(t.getEnclosingType());
  2626                 result *= 127;
  2627                 result += t.tsym.flatName().hashCode();
  2628                 for (Type s : t.getTypeArguments()) {
  2629                     result *= 127;
  2630                     result += visit(s);
  2632                 return result;
  2635             @Override
  2636             public Integer visitWildcardType(WildcardType t, Void ignored) {
  2637                 int result = t.kind.hashCode();
  2638                 if (t.type != null) {
  2639                     result *= 127;
  2640                     result += visit(t.type);
  2642                 return result;
  2645             @Override
  2646             public Integer visitArrayType(ArrayType t, Void ignored) {
  2647                 return visit(t.elemtype) + 12;
  2650             @Override
  2651             public Integer visitTypeVar(TypeVar t, Void ignored) {
  2652                 return System.identityHashCode(t.tsym);
  2655             @Override
  2656             public Integer visitUndetVar(UndetVar t, Void ignored) {
  2657                 return System.identityHashCode(t);
  2660             @Override
  2661             public Integer visitErrorType(ErrorType t, Void ignored) {
  2662                 return 0;
  2664         };
  2665     // </editor-fold>
  2667     // <editor-fold defaultstate="collapsed" desc="Return-Type-Substitutable">
  2668     /**
  2669      * Does t have a result that is a subtype of the result type of s,
  2670      * suitable for covariant returns?  It is assumed that both types
  2671      * are (possibly polymorphic) method types.  Monomorphic method
  2672      * types are handled in the obvious way.  Polymorphic method types
  2673      * require renaming all type variables of one to corresponding
  2674      * type variables in the other, where correspondence is by
  2675      * position in the type parameter list. */
  2676     public boolean resultSubtype(Type t, Type s, Warner warner) {
  2677         List<Type> tvars = t.getTypeArguments();
  2678         List<Type> svars = s.getTypeArguments();
  2679         Type tres = t.getReturnType();
  2680         Type sres = subst(s.getReturnType(), svars, tvars);
  2681         return covariantReturnType(tres, sres, warner);
  2684     /**
  2685      * Return-Type-Substitutable.
  2686      * @see <a href="http://java.sun.com/docs/books/jls/">The Java
  2687      * Language Specification, Third Ed. (8.4.5)</a>
  2688      */
  2689     public boolean returnTypeSubstitutable(Type r1, Type r2) {
  2690         if (hasSameArgs(r1, r2))
  2691             return resultSubtype(r1, r2, Warner.noWarnings);
  2692         else
  2693             return covariantReturnType(r1.getReturnType(),
  2694                                        erasure(r2.getReturnType()),
  2695                                        Warner.noWarnings);
  2698     public boolean returnTypeSubstitutable(Type r1,
  2699                                            Type r2, Type r2res,
  2700                                            Warner warner) {
  2701         if (isSameType(r1.getReturnType(), r2res))
  2702             return true;
  2703         if (r1.getReturnType().isPrimitive() || r2res.isPrimitive())
  2704             return false;
  2706         if (hasSameArgs(r1, r2))
  2707             return covariantReturnType(r1.getReturnType(), r2res, warner);
  2708         if (!source.allowCovariantReturns())
  2709             return false;
  2710         if (isSubtypeUnchecked(r1.getReturnType(), r2res, warner))
  2711             return true;
  2712         if (!isSubtype(r1.getReturnType(), erasure(r2res)))
  2713             return false;
  2714         warner.warnUnchecked();
  2715         return true;
  2718     /**
  2719      * Is t an appropriate return type in an overrider for a
  2720      * method that returns s?
  2721      */
  2722     public boolean covariantReturnType(Type t, Type s, Warner warner) {
  2723         return
  2724             isSameType(t, s) ||
  2725             source.allowCovariantReturns() &&
  2726             !t.isPrimitive() &&
  2727             !s.isPrimitive() &&
  2728             isAssignable(t, s, warner);
  2730     // </editor-fold>
  2732     // <editor-fold defaultstate="collapsed" desc="Box/unbox support">
  2733     /**
  2734      * Return the class that boxes the given primitive.
  2735      */
  2736     public ClassSymbol boxedClass(Type t) {
  2737         return reader.enterClass(syms.boxedName[t.tag]);
  2740     /**
  2741      * Return the primitive type corresponding to a boxed type.
  2742      */
  2743     public Type unboxedType(Type t) {
  2744         if (allowBoxing) {
  2745             for (int i=0; i<syms.boxedName.length; i++) {
  2746                 Name box = syms.boxedName[i];
  2747                 if (box != null &&
  2748                     asSuper(t, reader.enterClass(box)) != null)
  2749                     return syms.typeOfTag[i];
  2752         return Type.noType;
  2754     // </editor-fold>
  2756     // <editor-fold defaultstate="collapsed" desc="Capture conversion">
  2757     /*
  2758      * JLS 3rd Ed. 5.1.10 Capture Conversion:
  2760      * Let G name a generic type declaration with n formal type
  2761      * parameters A1 ... An with corresponding bounds U1 ... Un. There
  2762      * exists a capture conversion from G<T1 ... Tn> to G<S1 ... Sn>,
  2763      * where, for 1 <= i <= n:
  2765      * + If Ti is a wildcard type argument (4.5.1) of the form ? then
  2766      *   Si is a fresh type variable whose upper bound is
  2767      *   Ui[A1 := S1, ..., An := Sn] and whose lower bound is the null
  2768      *   type.
  2770      * + If Ti is a wildcard type argument of the form ? extends Bi,
  2771      *   then Si is a fresh type variable whose upper bound is
  2772      *   glb(Bi, Ui[A1 := S1, ..., An := Sn]) and whose lower bound is
  2773      *   the null type, where glb(V1,... ,Vm) is V1 & ... & Vm. It is
  2774      *   a compile-time error if for any two classes (not interfaces)
  2775      *   Vi and Vj,Vi is not a subclass of Vj or vice versa.
  2777      * + If Ti is a wildcard type argument of the form ? super Bi,
  2778      *   then Si is a fresh type variable whose upper bound is
  2779      *   Ui[A1 := S1, ..., An := Sn] and whose lower bound is Bi.
  2781      * + Otherwise, Si = Ti.
  2783      * Capture conversion on any type other than a parameterized type
  2784      * (4.5) acts as an identity conversion (5.1.1). Capture
  2785      * conversions never require a special action at run time and
  2786      * therefore never throw an exception at run time.
  2788      * Capture conversion is not applied recursively.
  2789      */
  2790     /**
  2791      * Capture conversion as specified by JLS 3rd Ed.
  2792      */
  2793     public Type capture(Type t) {
  2794         if (t.tag != CLASS)
  2795             return t;
  2796         ClassType cls = (ClassType)t;
  2797         if (cls.isRaw() || !cls.isParameterized())
  2798             return cls;
  2800         ClassType G = (ClassType)cls.asElement().asType();
  2801         List<Type> A = G.getTypeArguments();
  2802         List<Type> T = cls.getTypeArguments();
  2803         List<Type> S = freshTypeVariables(T);
  2805         List<Type> currentA = A;
  2806         List<Type> currentT = T;
  2807         List<Type> currentS = S;
  2808         boolean captured = false;
  2809         while (!currentA.isEmpty() &&
  2810                !currentT.isEmpty() &&
  2811                !currentS.isEmpty()) {
  2812             if (currentS.head != currentT.head) {
  2813                 captured = true;
  2814                 WildcardType Ti = (WildcardType)currentT.head;
  2815                 Type Ui = currentA.head.getUpperBound();
  2816                 CapturedType Si = (CapturedType)currentS.head;
  2817                 if (Ui == null)
  2818                     Ui = syms.objectType;
  2819                 switch (Ti.kind) {
  2820                 case UNBOUND:
  2821                     Si.bound = subst(Ui, A, S);
  2822                     Si.lower = syms.botType;
  2823                     break;
  2824                 case EXTENDS:
  2825                     Si.bound = glb(Ti.getExtendsBound(), subst(Ui, A, S));
  2826                     Si.lower = syms.botType;
  2827                     break;
  2828                 case SUPER:
  2829                     Si.bound = subst(Ui, A, S);
  2830                     Si.lower = Ti.getSuperBound();
  2831                     break;
  2833                 if (Si.bound == Si.lower)
  2834                     currentS.head = Si.bound;
  2836             currentA = currentA.tail;
  2837             currentT = currentT.tail;
  2838             currentS = currentS.tail;
  2840         if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty())
  2841             return erasure(t); // some "rare" type involved
  2843         if (captured)
  2844             return new ClassType(cls.getEnclosingType(), S, cls.tsym);
  2845         else
  2846             return t;
  2848     // where
  2849         private List<Type> freshTypeVariables(List<Type> types) {
  2850             ListBuffer<Type> result = lb();
  2851             for (Type t : types) {
  2852                 if (t.tag == WILDCARD) {
  2853                     Type bound = ((WildcardType)t).getExtendsBound();
  2854                     if (bound == null)
  2855                         bound = syms.objectType;
  2856                     result.append(new CapturedType(capturedName,
  2857                                                    syms.noSymbol,
  2858                                                    bound,
  2859                                                    syms.botType,
  2860                                                    (WildcardType)t));
  2861                 } else {
  2862                     result.append(t);
  2865             return result.toList();
  2867     // </editor-fold>
  2869     // <editor-fold defaultstate="collapsed" desc="Internal utility methods">
  2870     private List<Type> upperBounds(List<Type> ss) {
  2871         if (ss.isEmpty()) return ss;
  2872         Type head = upperBound(ss.head);
  2873         List<Type> tail = upperBounds(ss.tail);
  2874         if (head != ss.head || tail != ss.tail)
  2875             return tail.prepend(head);
  2876         else
  2877             return ss;
  2880     private boolean sideCast(Type from, Type to, Warner warn) {
  2881         // We are casting from type $from$ to type $to$, which are
  2882         // non-final unrelated types.  This method
  2883         // tries to reject a cast by transferring type parameters
  2884         // from $to$ to $from$ by common superinterfaces.
  2885         boolean reverse = false;
  2886         Type target = to;
  2887         if ((to.tsym.flags() & INTERFACE) == 0) {
  2888             assert (from.tsym.flags() & INTERFACE) != 0;
  2889             reverse = true;
  2890             to = from;
  2891             from = target;
  2893         List<Type> commonSupers = superClosure(to, erasure(from));
  2894         boolean giveWarning = commonSupers.isEmpty();
  2895         // The arguments to the supers could be unified here to
  2896         // get a more accurate analysis
  2897         while (commonSupers.nonEmpty()) {
  2898             Type t1 = asSuper(from, commonSupers.head.tsym);
  2899             Type t2 = commonSupers.head; // same as asSuper(to, commonSupers.head.tsym);
  2900             if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
  2901                 return false;
  2902             giveWarning = giveWarning || (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2));
  2903             commonSupers = commonSupers.tail;
  2905         if (giveWarning && !isReifiable(to))
  2906             warn.warnUnchecked();
  2907         if (!source.allowCovariantReturns())
  2908             // reject if there is a common method signature with
  2909             // incompatible return types.
  2910             chk.checkCompatibleAbstracts(warn.pos(), from, to);
  2911         return true;
  2914     private boolean sideCastFinal(Type from, Type to, Warner warn) {
  2915         // We are casting from type $from$ to type $to$, which are
  2916         // unrelated types one of which is final and the other of
  2917         // which is an interface.  This method
  2918         // tries to reject a cast by transferring type parameters
  2919         // from the final class to the interface.
  2920         boolean reverse = false;
  2921         Type target = to;
  2922         if ((to.tsym.flags() & INTERFACE) == 0) {
  2923             assert (from.tsym.flags() & INTERFACE) != 0;
  2924             reverse = true;
  2925             to = from;
  2926             from = target;
  2928         assert (from.tsym.flags() & FINAL) != 0;
  2929         Type t1 = asSuper(from, to.tsym);
  2930         if (t1 == null) return false;
  2931         Type t2 = to;
  2932         if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
  2933             return false;
  2934         if (!source.allowCovariantReturns())
  2935             // reject if there is a common method signature with
  2936             // incompatible return types.
  2937             chk.checkCompatibleAbstracts(warn.pos(), from, to);
  2938         if (!isReifiable(target) &&
  2939             (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2)))
  2940             warn.warnUnchecked();
  2941         return true;
  2944     private boolean giveWarning(Type from, Type to) {
  2945         // To and from are (possibly different) parameterizations
  2946         // of the same class or interface
  2947         return to.isParameterized() && !containsType(to.getTypeArguments(), from.getTypeArguments());
  2950     private List<Type> superClosure(Type t, Type s) {
  2951         List<Type> cl = List.nil();
  2952         for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
  2953             if (isSubtype(s, erasure(l.head))) {
  2954                 cl = insert(cl, l.head);
  2955             } else {
  2956                 cl = union(cl, superClosure(l.head, s));
  2959         return cl;
  2962     private boolean containsTypeEquivalent(Type t, Type s) {
  2963         return
  2964             isSameType(t, s) || // shortcut
  2965             containsType(t, s) && containsType(s, t);
  2968     /**
  2969      * Adapt a type by computing a substitution which maps a source
  2970      * type to a target type.
  2972      * @param source    the source type
  2973      * @param target    the target type
  2974      * @param from      the type variables of the computed substitution
  2975      * @param to        the types of the computed substitution.
  2976      */
  2977     public void adapt(Type source,
  2978                        Type target,
  2979                        ListBuffer<Type> from,
  2980                        ListBuffer<Type> to) throws AdaptFailure {
  2981         Map<Symbol,Type> mapping = new HashMap<Symbol,Type>();
  2982         adaptRecursive(source, target, from, to, mapping);
  2983         List<Type> fromList = from.toList();
  2984         List<Type> toList = to.toList();
  2985         while (!fromList.isEmpty()) {
  2986             Type val = mapping.get(fromList.head.tsym);
  2987             if (toList.head != val)
  2988                 toList.head = val;
  2989             fromList = fromList.tail;
  2990             toList = toList.tail;
  2993     // where
  2994         private void adaptRecursive(Type source,
  2995                                     Type target,
  2996                                     ListBuffer<Type> from,
  2997                                     ListBuffer<Type> to,
  2998                                     Map<Symbol,Type> mapping) throws AdaptFailure {
  2999             if (source.tag == TYPEVAR) {
  3000                 // Check to see if there is
  3001                 // already a mapping for $source$, in which case
  3002                 // the old mapping will be merged with the new
  3003                 Type val = mapping.get(source.tsym);
  3004                 if (val != null) {
  3005                     if (val.isSuperBound() && target.isSuperBound()) {
  3006                         val = isSubtype(lowerBound(val), lowerBound(target))
  3007                             ? target : val;
  3008                     } else if (val.isExtendsBound() && target.isExtendsBound()) {
  3009                         val = isSubtype(upperBound(val), upperBound(target))
  3010                             ? val : target;
  3011                     } else if (!isSameType(val, target)) {
  3012                         throw new AdaptFailure();
  3014                 } else {
  3015                     val = target;
  3016                     from.append(source);
  3017                     to.append(target);
  3019                 mapping.put(source.tsym, val);
  3020             } else if (source.tag == target.tag) {
  3021                 switch (source.tag) {
  3022                     case CLASS:
  3023                         adapt(source.allparams(), target.allparams(),
  3024                               from, to, mapping);
  3025                         break;
  3026                     case ARRAY:
  3027                         adaptRecursive(elemtype(source), elemtype(target),
  3028                                        from, to, mapping);
  3029                         break;
  3030                     case WILDCARD:
  3031                         if (source.isExtendsBound()) {
  3032                             adaptRecursive(upperBound(source), upperBound(target),
  3033                                            from, to, mapping);
  3034                         } else if (source.isSuperBound()) {
  3035                             adaptRecursive(lowerBound(source), lowerBound(target),
  3036                                            from, to, mapping);
  3038                         break;
  3042         public static class AdaptFailure extends Exception {
  3043             static final long serialVersionUID = -7490231548272701566L;
  3046     /**
  3047      * Adapt a type by computing a substitution which maps a list of
  3048      * source types to a list of target types.
  3050      * @param source    the source type
  3051      * @param target    the target type
  3052      * @param from      the type variables of the computed substitution
  3053      * @param to        the types of the computed substitution.
  3054      */
  3055     private void adapt(List<Type> source,
  3056                        List<Type> target,
  3057                        ListBuffer<Type> from,
  3058                        ListBuffer<Type> to,
  3059                        Map<Symbol,Type> mapping) throws AdaptFailure {
  3060         if (source.length() == target.length()) {
  3061             while (source.nonEmpty()) {
  3062                 adaptRecursive(source.head, target.head, from, to, mapping);
  3063                 source = source.tail;
  3064                 target = target.tail;
  3069     private void adaptSelf(Type t,
  3070                            ListBuffer<Type> from,
  3071                            ListBuffer<Type> to) {
  3072         try {
  3073             //if (t.tsym.type != t)
  3074                 adapt(t.tsym.type, t, from, to);
  3075         } catch (AdaptFailure ex) {
  3076             // Adapt should never fail calculating a mapping from
  3077             // t.tsym.type to t as there can be no merge problem.
  3078             throw new AssertionError(ex);
  3082     /**
  3083      * Rewrite all type variables (universal quantifiers) in the given
  3084      * type to wildcards (existential quantifiers).  This is used to
  3085      * determine if a cast is allowed.  For example, if high is true
  3086      * and {@code T <: Number}, then {@code List<T>} is rewritten to
  3087      * {@code List<?  extends Number>}.  Since {@code List<Integer> <:
  3088      * List<? extends Number>} a {@code List<T>} can be cast to {@code
  3089      * List<Integer>} with a warning.
  3090      * @param t a type
  3091      * @param high if true return an upper bound; otherwise a lower
  3092      * bound
  3093      * @param rewriteTypeVars only rewrite captured wildcards if false;
  3094      * otherwise rewrite all type variables
  3095      * @return the type rewritten with wildcards (existential
  3096      * quantifiers) only
  3097      */
  3098     private Type rewriteQuantifiers(Type t, boolean high, boolean rewriteTypeVars) {
  3099         ListBuffer<Type> from = new ListBuffer<Type>();
  3100         ListBuffer<Type> to = new ListBuffer<Type>();
  3101         adaptSelf(t, from, to);
  3102         ListBuffer<Type> rewritten = new ListBuffer<Type>();
  3103         List<Type> formals = from.toList();
  3104         boolean changed = false;
  3105         for (Type arg : to.toList()) {
  3106             Type bound;
  3107             if (rewriteTypeVars && arg.tag == TYPEVAR) {
  3108                 TypeVar tv = (TypeVar)arg;
  3109                 bound = high ? tv.bound : syms.botType;
  3110             } else {
  3111                 bound = high ? upperBound(arg) : lowerBound(arg);
  3113             Type newarg = bound;
  3114             if (arg != bound) {
  3115                 changed = true;
  3116                 newarg = high ? makeExtendsWildcard(bound, (TypeVar)formals.head)
  3117                               : makeSuperWildcard(bound, (TypeVar)formals.head);
  3119             rewritten.append(newarg);
  3120             formals = formals.tail;
  3122         if (changed)
  3123             return subst(t.tsym.type, from.toList(), rewritten.toList());
  3124         else
  3125             return t;
  3128     /**
  3129      * Create a wildcard with the given upper (extends) bound; create
  3130      * an unbounded wildcard if bound is Object.
  3132      * @param bound the upper bound
  3133      * @param formal the formal type parameter that will be
  3134      * substituted by the wildcard
  3135      */
  3136     private WildcardType makeExtendsWildcard(Type bound, TypeVar formal) {
  3137         if (bound == syms.objectType) {
  3138             return new WildcardType(syms.objectType,
  3139                                     BoundKind.UNBOUND,
  3140                                     syms.boundClass,
  3141                                     formal);
  3142         } else {
  3143             return new WildcardType(bound,
  3144                                     BoundKind.EXTENDS,
  3145                                     syms.boundClass,
  3146                                     formal);
  3150     /**
  3151      * Create a wildcard with the given lower (super) bound; create an
  3152      * unbounded wildcard if bound is bottom (type of {@code null}).
  3154      * @param bound the lower bound
  3155      * @param formal the formal type parameter that will be
  3156      * substituted by the wildcard
  3157      */
  3158     private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
  3159         if (bound.tag == BOT) {
  3160             return new WildcardType(syms.objectType,
  3161                                     BoundKind.UNBOUND,
  3162                                     syms.boundClass,
  3163                                     formal);
  3164         } else {
  3165             return new WildcardType(bound,
  3166                                     BoundKind.SUPER,
  3167                                     syms.boundClass,
  3168                                     formal);
  3172     /**
  3173      * A wrapper for a type that allows use in sets.
  3174      */
  3175     class SingletonType {
  3176         final Type t;
  3177         SingletonType(Type t) {
  3178             this.t = t;
  3180         public int hashCode() {
  3181             return Types.this.hashCode(t);
  3183         public boolean equals(Object obj) {
  3184             return (obj instanceof SingletonType) &&
  3185                 isSameType(t, ((SingletonType)obj).t);
  3187         public String toString() {
  3188             return t.toString();
  3191     // </editor-fold>
  3193     // <editor-fold defaultstate="collapsed" desc="Visitors">
  3194     /**
  3195      * A default visitor for types.  All visitor methods except
  3196      * visitType are implemented by delegating to visitType.  Concrete
  3197      * subclasses must provide an implementation of visitType and can
  3198      * override other methods as needed.
  3200      * @param <R> the return type of the operation implemented by this
  3201      * visitor; use Void if no return type is needed.
  3202      * @param <S> the type of the second argument (the first being the
  3203      * type itself) of the operation implemented by this visitor; use
  3204      * Void if a second argument is not needed.
  3205      */
  3206     public static abstract class DefaultTypeVisitor<R,S> implements Type.Visitor<R,S> {
  3207         final public R visit(Type t, S s)               { return t.accept(this, s); }
  3208         public R visitClassType(ClassType t, S s)       { return visitType(t, s); }
  3209         public R visitWildcardType(WildcardType t, S s) { return visitType(t, s); }
  3210         public R visitArrayType(ArrayType t, S s)       { return visitType(t, s); }
  3211         public R visitMethodType(MethodType t, S s)     { return visitType(t, s); }
  3212         public R visitPackageType(PackageType t, S s)   { return visitType(t, s); }
  3213         public R visitTypeVar(TypeVar t, S s)           { return visitType(t, s); }
  3214         public R visitCapturedType(CapturedType t, S s) { return visitType(t, s); }
  3215         public R visitForAll(ForAll t, S s)             { return visitType(t, s); }
  3216         public R visitUndetVar(UndetVar t, S s)         { return visitType(t, s); }
  3217         public R visitErrorType(ErrorType t, S s)       { return visitType(t, s); }
  3220     /**
  3221      * A <em>simple</em> visitor for types.  This visitor is simple as
  3222      * captured wildcards, for-all types (generic methods), and
  3223      * undetermined type variables (part of inference) are hidden.
  3224      * Captured wildcards are hidden by treating them as type
  3225      * variables and the rest are hidden by visiting their qtypes.
  3227      * @param <R> the return type of the operation implemented by this
  3228      * visitor; use Void if no return type is needed.
  3229      * @param <S> the type of the second argument (the first being the
  3230      * type itself) of the operation implemented by this visitor; use
  3231      * Void if a second argument is not needed.
  3232      */
  3233     public static abstract class SimpleVisitor<R,S> extends DefaultTypeVisitor<R,S> {
  3234         @Override
  3235         public R visitCapturedType(CapturedType t, S s) {
  3236             return visitTypeVar(t, s);
  3238         @Override
  3239         public R visitForAll(ForAll t, S s) {
  3240             return visit(t.qtype, s);
  3242         @Override
  3243         public R visitUndetVar(UndetVar t, S s) {
  3244             return visit(t.qtype, s);
  3248     /**
  3249      * A plain relation on types.  That is a 2-ary function on the
  3250      * form Type&nbsp;&times;&nbsp;Type&nbsp;&rarr;&nbsp;Boolean.
  3251      * <!-- In plain text: Type x Type -> Boolean -->
  3252      */
  3253     public static abstract class TypeRelation extends SimpleVisitor<Boolean,Type> {}
  3255     /**
  3256      * A convenience visitor for implementing operations that only
  3257      * require one argument (the type itself), that is, unary
  3258      * operations.
  3260      * @param <R> the return type of the operation implemented by this
  3261      * visitor; use Void if no return type is needed.
  3262      */
  3263     public static abstract class UnaryVisitor<R> extends SimpleVisitor<R,Void> {
  3264         final public R visit(Type t) { return t.accept(this, null); }
  3267     /**
  3268      * A visitor for implementing a mapping from types to types.  The
  3269      * default behavior of this class is to implement the identity
  3270      * mapping (mapping a type to itself).  This can be overridden in
  3271      * subclasses.
  3273      * @param <S> the type of the second argument (the first being the
  3274      * type itself) of this mapping; use Void if a second argument is
  3275      * not needed.
  3276      */
  3277     public static class MapVisitor<S> extends DefaultTypeVisitor<Type,S> {
  3278         final public Type visit(Type t) { return t.accept(this, null); }
  3279         public Type visitType(Type t, S s) { return t; }
  3281     // </editor-fold>

mercurial