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

Wed, 02 Apr 2008 11:44:23 +0100

author
mcimadamore
date
Wed, 02 Apr 2008 11:44:23 +0100
changeset 19
adaa3fc51b60
parent 5
b45f8d4794b7
child 30
a1d1f335633f
permissions
-rw-r--r--

6531090: Cannot access methods/fields of a captured type belonging to an intersection type
Summary: fixed lookup of field/methods on intersection types
Reviewed-by: jjg

     1 /*
     2  * Copyright 2003-2006 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         } else if (!s.isRaw()) {
   305             Type t2 = asSuper(t, s.tsym);
   306             if (t2 != null && t2.isRaw()) {
   307                 if (isReifiable(s))
   308                     warn.silentUnchecked();
   309                 else
   310                     warn.warnUnchecked();
   311                 return true;
   312             }
   313         }
   314         return false;
   315     }
   317     /**
   318      * Is t a subtype of s?<br>
   319      * (not defined for Method and ForAll types)
   320      */
   321     final public boolean isSubtype(Type t, Type s) {
   322         return isSubtype(t, s, true);
   323     }
   324     final public boolean isSubtypeNoCapture(Type t, Type s) {
   325         return isSubtype(t, s, false);
   326     }
   327     public boolean isSubtype(Type t, Type s, boolean capture) {
   328         if (t == s)
   329             return true;
   331         if (s.tag >= firstPartialTag)
   332             return isSuperType(s, t);
   334         Type lower = lowerBound(s);
   335         if (s != lower)
   336             return isSubtype(capture ? capture(t) : t, lower, false);
   338         return isSubtype.visit(capture ? capture(t) : t, s);
   339     }
   340     // where
   341         private TypeRelation isSubtype = new TypeRelation()
   342         {
   343             public Boolean visitType(Type t, Type s) {
   344                 switch (t.tag) {
   345                 case BYTE: case CHAR:
   346                     return (t.tag == s.tag ||
   347                               t.tag + 2 <= s.tag && s.tag <= DOUBLE);
   348                 case SHORT: case INT: case LONG: case FLOAT: case DOUBLE:
   349                     return t.tag <= s.tag && s.tag <= DOUBLE;
   350                 case BOOLEAN: case VOID:
   351                     return t.tag == s.tag;
   352                 case TYPEVAR:
   353                     return isSubtypeNoCapture(t.getUpperBound(), s);
   354                 case BOT:
   355                     return
   356                         s.tag == BOT || s.tag == CLASS ||
   357                         s.tag == ARRAY || s.tag == TYPEVAR;
   358                 case NONE:
   359                     return false;
   360                 default:
   361                     throw new AssertionError("isSubtype " + t.tag);
   362                 }
   363             }
   365             private Set<TypePair> cache = new HashSet<TypePair>();
   367             private boolean containsTypeRecursive(Type t, Type s) {
   368                 TypePair pair = new TypePair(t, s);
   369                 if (cache.add(pair)) {
   370                     try {
   371                         return containsType(t.getTypeArguments(),
   372                                             s.getTypeArguments());
   373                     } finally {
   374                         cache.remove(pair);
   375                     }
   376                 } else {
   377                     return containsType(t.getTypeArguments(),
   378                                         rewriteSupers(s).getTypeArguments());
   379                 }
   380             }
   382             private Type rewriteSupers(Type t) {
   383                 if (!t.isParameterized())
   384                     return t;
   385                 ListBuffer<Type> from = lb();
   386                 ListBuffer<Type> to = lb();
   387                 adaptSelf(t, from, to);
   388                 if (from.isEmpty())
   389                     return t;
   390                 ListBuffer<Type> rewrite = lb();
   391                 boolean changed = false;
   392                 for (Type orig : to.toList()) {
   393                     Type s = rewriteSupers(orig);
   394                     if (s.isSuperBound() && !s.isExtendsBound()) {
   395                         s = new WildcardType(syms.objectType,
   396                                              BoundKind.UNBOUND,
   397                                              syms.boundClass);
   398                         changed = true;
   399                     } else if (s != orig) {
   400                         s = new WildcardType(upperBound(s),
   401                                              BoundKind.EXTENDS,
   402                                              syms.boundClass);
   403                         changed = true;
   404                     }
   405                     rewrite.append(s);
   406                 }
   407                 if (changed)
   408                     return subst(t.tsym.type, from.toList(), rewrite.toList());
   409                 else
   410                     return t;
   411             }
   413             @Override
   414             public Boolean visitClassType(ClassType t, Type s) {
   415                 Type sup = asSuper(t, s.tsym);
   416                 return sup != null
   417                     && sup.tsym == s.tsym
   418                     // You're not allowed to write
   419                     //     Vector<Object> vec = new Vector<String>();
   420                     // But with wildcards you can write
   421                     //     Vector<? extends Object> vec = new Vector<String>();
   422                     // which means that subtype checking must be done
   423                     // here instead of same-type checking (via containsType).
   424                     && (!s.isParameterized() || containsTypeRecursive(s, sup))
   425                     && isSubtypeNoCapture(sup.getEnclosingType(),
   426                                           s.getEnclosingType());
   427             }
   429             @Override
   430             public Boolean visitArrayType(ArrayType t, Type s) {
   431                 if (s.tag == ARRAY) {
   432                     if (t.elemtype.tag <= lastBaseTag)
   433                         return isSameType(t.elemtype, elemtype(s));
   434                     else
   435                         return isSubtypeNoCapture(t.elemtype, elemtype(s));
   436                 }
   438                 if (s.tag == CLASS) {
   439                     Name sname = s.tsym.getQualifiedName();
   440                     return sname == names.java_lang_Object
   441                         || sname == names.java_lang_Cloneable
   442                         || sname == names.java_io_Serializable;
   443                 }
   445                 return false;
   446             }
   448             @Override
   449             public Boolean visitUndetVar(UndetVar t, Type s) {
   450                 //todo: test against origin needed? or replace with substitution?
   451                 if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN)
   452                     return true;
   454                 if (t.inst != null)
   455                     return isSubtypeNoCapture(t.inst, s); // TODO: ", warn"?
   457                 t.hibounds = t.hibounds.prepend(s);
   458                 return true;
   459             }
   461             @Override
   462             public Boolean visitErrorType(ErrorType t, Type s) {
   463                 return true;
   464             }
   465         };
   467     /**
   468      * Is t a subtype of every type in given list `ts'?<br>
   469      * (not defined for Method and ForAll types)<br>
   470      * Allows unchecked conversions.
   471      */
   472     public boolean isSubtypeUnchecked(Type t, List<Type> ts, Warner warn) {
   473         for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
   474             if (!isSubtypeUnchecked(t, l.head, warn))
   475                 return false;
   476         return true;
   477     }
   479     /**
   480      * Are corresponding elements of ts subtypes of ss?  If lists are
   481      * of different length, return false.
   482      */
   483     public boolean isSubtypes(List<Type> ts, List<Type> ss) {
   484         while (ts.tail != null && ss.tail != null
   485                /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
   486                isSubtype(ts.head, ss.head)) {
   487             ts = ts.tail;
   488             ss = ss.tail;
   489         }
   490         return ts.tail == null && ss.tail == null;
   491         /*inlined: ts.isEmpty() && ss.isEmpty();*/
   492     }
   494     /**
   495      * Are corresponding elements of ts subtypes of ss, allowing
   496      * unchecked conversions?  If lists are of different length,
   497      * return false.
   498      **/
   499     public boolean isSubtypesUnchecked(List<Type> ts, List<Type> ss, Warner warn) {
   500         while (ts.tail != null && ss.tail != null
   501                /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
   502                isSubtypeUnchecked(ts.head, ss.head, warn)) {
   503             ts = ts.tail;
   504             ss = ss.tail;
   505         }
   506         return ts.tail == null && ss.tail == null;
   507         /*inlined: ts.isEmpty() && ss.isEmpty();*/
   508     }
   509     // </editor-fold>
   511     // <editor-fold defaultstate="collapsed" desc="isSuperType">
   512     /**
   513      * Is t a supertype of s?
   514      */
   515     public boolean isSuperType(Type t, Type s) {
   516         switch (t.tag) {
   517         case ERROR:
   518             return true;
   519         case UNDETVAR: {
   520             UndetVar undet = (UndetVar)t;
   521             if (t == s ||
   522                 undet.qtype == s ||
   523                 s.tag == ERROR ||
   524                 s.tag == BOT) return true;
   525             if (undet.inst != null)
   526                 return isSubtype(s, undet.inst);
   527             undet.lobounds = undet.lobounds.prepend(s);
   528             return true;
   529         }
   530         default:
   531             return isSubtype(s, t);
   532         }
   533     }
   534     // </editor-fold>
   536     // <editor-fold defaultstate="collapsed" desc="isSameType">
   537     /**
   538      * Are corresponding elements of the lists the same type?  If
   539      * lists are of different length, return false.
   540      */
   541     public boolean isSameTypes(List<Type> ts, List<Type> ss) {
   542         while (ts.tail != null && ss.tail != null
   543                /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
   544                isSameType(ts.head, ss.head)) {
   545             ts = ts.tail;
   546             ss = ss.tail;
   547         }
   548         return ts.tail == null && ss.tail == null;
   549         /*inlined: ts.isEmpty() && ss.isEmpty();*/
   550     }
   552     /**
   553      * Is t the same type as s?
   554      */
   555     public boolean isSameType(Type t, Type s) {
   556         return isSameType.visit(t, s);
   557     }
   558     // where
   559         private TypeRelation isSameType = new TypeRelation() {
   561             public Boolean visitType(Type t, Type s) {
   562                 if (t == s)
   563                     return true;
   565                 if (s.tag >= firstPartialTag)
   566                     return visit(s, t);
   568                 switch (t.tag) {
   569                 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
   570                 case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE:
   571                     return t.tag == s.tag;
   572                 case TYPEVAR:
   573                     return s.isSuperBound()
   574                         && !s.isExtendsBound()
   575                         && visit(t, upperBound(s));
   576                 default:
   577                     throw new AssertionError("isSameType " + t.tag);
   578                 }
   579             }
   581             @Override
   582             public Boolean visitWildcardType(WildcardType t, Type s) {
   583                 if (s.tag >= firstPartialTag)
   584                     return visit(s, t);
   585                 else
   586                     return false;
   587             }
   589             @Override
   590             public Boolean visitClassType(ClassType t, Type s) {
   591                 if (t == s)
   592                     return true;
   594                 if (s.tag >= firstPartialTag)
   595                     return visit(s, t);
   597                 if (s.isSuperBound() && !s.isExtendsBound())
   598                     return visit(t, upperBound(s)) && visit(t, lowerBound(s));
   600                 if (t.isCompound() && s.isCompound()) {
   601                     if (!visit(supertype(t), supertype(s)))
   602                         return false;
   604                     HashSet<SingletonType> set = new HashSet<SingletonType>();
   605                     for (Type x : interfaces(t))
   606                         set.add(new SingletonType(x));
   607                     for (Type x : interfaces(s)) {
   608                         if (!set.remove(new SingletonType(x)))
   609                             return false;
   610                     }
   611                     return (set.size() == 0);
   612                 }
   613                 return t.tsym == s.tsym
   614                     && visit(t.getEnclosingType(), s.getEnclosingType())
   615                     && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments());
   616             }
   618             @Override
   619             public Boolean visitArrayType(ArrayType t, Type s) {
   620                 if (t == s)
   621                     return true;
   623                 if (s.tag >= firstPartialTag)
   624                     return visit(s, t);
   626                 return s.tag == ARRAY
   627                     && containsTypeEquivalent(t.elemtype, elemtype(s));
   628             }
   630             @Override
   631             public Boolean visitMethodType(MethodType t, Type s) {
   632                 // isSameType for methods does not take thrown
   633                 // exceptions into account!
   634                 return hasSameArgs(t, s) && visit(t.getReturnType(), s.getReturnType());
   635             }
   637             @Override
   638             public Boolean visitPackageType(PackageType t, Type s) {
   639                 return t == s;
   640             }
   642             @Override
   643             public Boolean visitForAll(ForAll t, Type s) {
   644                 if (s.tag != FORALL)
   645                     return false;
   647                 ForAll forAll = (ForAll)s;
   648                 return hasSameBounds(t, forAll)
   649                     && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
   650             }
   652             @Override
   653             public Boolean visitUndetVar(UndetVar t, Type s) {
   654                 if (s.tag == WILDCARD)
   655                     // FIXME, this might be leftovers from before capture conversion
   656                     return false;
   658                 if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN)
   659                     return true;
   661                 if (t.inst != null)
   662                     return visit(t.inst, s);
   664                 t.inst = fromUnknownFun.apply(s);
   665                 for (List<Type> l = t.lobounds; l.nonEmpty(); l = l.tail) {
   666                     if (!isSubtype(l.head, t.inst))
   667                         return false;
   668                 }
   669                 for (List<Type> l = t.hibounds; l.nonEmpty(); l = l.tail) {
   670                     if (!isSubtype(t.inst, l.head))
   671                         return false;
   672                 }
   673                 return true;
   674             }
   676             @Override
   677             public Boolean visitErrorType(ErrorType t, Type s) {
   678                 return true;
   679             }
   680         };
   681     // </editor-fold>
   683     // <editor-fold defaultstate="collapsed" desc="fromUnknownFun">
   684     /**
   685      * A mapping that turns all unknown types in this type to fresh
   686      * unknown variables.
   687      */
   688     public Mapping fromUnknownFun = new Mapping("fromUnknownFun") {
   689             public Type apply(Type t) {
   690                 if (t.tag == UNKNOWN) return new UndetVar(t);
   691                 else return t.map(this);
   692             }
   693         };
   694     // </editor-fold>
   696     // <editor-fold defaultstate="collapsed" desc="Contains Type">
   697     public boolean containedBy(Type t, Type s) {
   698         switch (t.tag) {
   699         case UNDETVAR:
   700             if (s.tag == WILDCARD) {
   701                 UndetVar undetvar = (UndetVar)t;
   703                 // Because of wildcard capture, s must be on the left
   704                 // hand side of an assignment.  Furthermore, t is an
   705                 // underconstrained type variable, for example, one
   706                 // that is only used in the return type of a method.
   707                 // If the type variable is truly underconstrained, it
   708                 // cannot have any low bounds:
   709                 assert undetvar.lobounds.isEmpty() : undetvar;
   711                 undetvar.inst = glb(upperBound(s), undetvar.inst);
   712                 return true;
   713             } else {
   714                 return isSameType(t, s);
   715             }
   716         case ERROR:
   717             return true;
   718         default:
   719             return containsType(s, t);
   720         }
   721     }
   723     boolean containsType(List<Type> ts, List<Type> ss) {
   724         while (ts.nonEmpty() && ss.nonEmpty()
   725                && containsType(ts.head, ss.head)) {
   726             ts = ts.tail;
   727             ss = ss.tail;
   728         }
   729         return ts.isEmpty() && ss.isEmpty();
   730     }
   732     /**
   733      * Check if t contains s.
   734      *
   735      * <p>T contains S if:
   736      *
   737      * <p>{@code L(T) <: L(S) && U(S) <: U(T)}
   738      *
   739      * <p>This relation is only used by ClassType.isSubtype(), that
   740      * is,
   741      *
   742      * <p>{@code C<S> <: C<T> if T contains S.}
   743      *
   744      * <p>Because of F-bounds, this relation can lead to infinite
   745      * recursion.  Thus we must somehow break that recursion.  Notice
   746      * that containsType() is only called from ClassType.isSubtype().
   747      * Since the arguments have already been checked against their
   748      * bounds, we know:
   749      *
   750      * <p>{@code U(S) <: U(T) if T is "super" bound (U(T) *is* the bound)}
   751      *
   752      * <p>{@code L(T) <: L(S) if T is "extends" bound (L(T) is bottom)}
   753      *
   754      * @param t a type
   755      * @param s a type
   756      */
   757     public boolean containsType(Type t, Type s) {
   758         return containsType.visit(t, s);
   759     }
   760     // where
   761         private TypeRelation containsType = new TypeRelation() {
   763             private Type U(Type t) {
   764                 while (t.tag == WILDCARD) {
   765                     WildcardType w = (WildcardType)t;
   766                     if (w.isSuperBound())
   767                         return w.bound == null ? syms.objectType : w.bound.bound;
   768                     else
   769                         t = w.type;
   770                 }
   771                 return t;
   772             }
   774             private Type L(Type t) {
   775                 while (t.tag == WILDCARD) {
   776                     WildcardType w = (WildcardType)t;
   777                     if (w.isExtendsBound())
   778                         return syms.botType;
   779                     else
   780                         t = w.type;
   781                 }
   782                 return t;
   783             }
   785             public Boolean visitType(Type t, Type s) {
   786                 if (s.tag >= firstPartialTag)
   787                     return containedBy(s, t);
   788                 else
   789                     return isSameType(t, s);
   790             }
   792             void debugContainsType(WildcardType t, Type s) {
   793                 System.err.println();
   794                 System.err.format(" does %s contain %s?%n", t, s);
   795                 System.err.format(" %s U(%s) <: U(%s) %s = %s%n",
   796                                   upperBound(s), s, t, U(t),
   797                                   t.isSuperBound()
   798                                   || isSubtypeNoCapture(upperBound(s), U(t)));
   799                 System.err.format(" %s L(%s) <: L(%s) %s = %s%n",
   800                                   L(t), t, s, lowerBound(s),
   801                                   t.isExtendsBound()
   802                                   || isSubtypeNoCapture(L(t), lowerBound(s)));
   803                 System.err.println();
   804             }
   806             @Override
   807             public Boolean visitWildcardType(WildcardType t, Type s) {
   808                 if (s.tag >= firstPartialTag)
   809                     return containedBy(s, t);
   810                 else {
   811                     // debugContainsType(t, s);
   812                     return isSameWildcard(t, s)
   813                         || isCaptureOf(s, t)
   814                         || ((t.isExtendsBound() || isSubtypeNoCapture(L(t), lowerBound(s))) &&
   815                             (t.isSuperBound() || isSubtypeNoCapture(upperBound(s), U(t))));
   816                 }
   817             }
   819             @Override
   820             public Boolean visitUndetVar(UndetVar t, Type s) {
   821                 if (s.tag != WILDCARD)
   822                     return isSameType(t, s);
   823                 else
   824                     return false;
   825             }
   827             @Override
   828             public Boolean visitErrorType(ErrorType t, Type s) {
   829                 return true;
   830             }
   831         };
   833     public boolean isCaptureOf(Type s, WildcardType t) {
   834         if (s.tag != TYPEVAR || !(s instanceof CapturedType))
   835             return false;
   836         return isSameWildcard(t, ((CapturedType)s).wildcard);
   837     }
   839     public boolean isSameWildcard(WildcardType t, Type s) {
   840         if (s.tag != WILDCARD)
   841             return false;
   842         WildcardType w = (WildcardType)s;
   843         return w.kind == t.kind && w.type == t.type;
   844     }
   846     public boolean containsTypeEquivalent(List<Type> ts, List<Type> ss) {
   847         while (ts.nonEmpty() && ss.nonEmpty()
   848                && containsTypeEquivalent(ts.head, ss.head)) {
   849             ts = ts.tail;
   850             ss = ss.tail;
   851         }
   852         return ts.isEmpty() && ss.isEmpty();
   853     }
   854     // </editor-fold>
   856     // <editor-fold defaultstate="collapsed" desc="isCastable">
   857     public boolean isCastable(Type t, Type s) {
   858         return isCastable(t, s, Warner.noWarnings);
   859     }
   861     /**
   862      * Is t is castable to s?<br>
   863      * s is assumed to be an erased type.<br>
   864      * (not defined for Method and ForAll types).
   865      */
   866     public boolean isCastable(Type t, Type s, Warner warn) {
   867         if (t == s)
   868             return true;
   870         if (t.isPrimitive() != s.isPrimitive())
   871             return allowBoxing && isConvertible(t, s, warn);
   873         if (warn != warnStack.head) {
   874             try {
   875                 warnStack = warnStack.prepend(warn);
   876                 return isCastable.visit(t, s);
   877             } finally {
   878                 warnStack = warnStack.tail;
   879             }
   880         } else {
   881             return isCastable.visit(t, s);
   882         }
   883     }
   884     // where
   885         private TypeRelation isCastable = new TypeRelation() {
   887             public Boolean visitType(Type t, Type s) {
   888                 if (s.tag == ERROR)
   889                     return true;
   891                 switch (t.tag) {
   892                 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
   893                 case DOUBLE:
   894                     return s.tag <= DOUBLE;
   895                 case BOOLEAN:
   896                     return s.tag == BOOLEAN;
   897                 case VOID:
   898                     return false;
   899                 case BOT:
   900                     return isSubtype(t, s);
   901                 default:
   902                     throw new AssertionError();
   903                 }
   904             }
   906             @Override
   907             public Boolean visitWildcardType(WildcardType t, Type s) {
   908                 return isCastable(upperBound(t), s, warnStack.head);
   909             }
   911             @Override
   912             public Boolean visitClassType(ClassType t, Type s) {
   913                 if (s.tag == ERROR || s.tag == BOT)
   914                     return true;
   916                 if (s.tag == TYPEVAR) {
   917                     if (isCastable(s.getUpperBound(), t, Warner.noWarnings)) {
   918                         warnStack.head.warnUnchecked();
   919                         return true;
   920                     } else {
   921                         return false;
   922                     }
   923                 }
   925                 if (t.isCompound()) {
   926                     if (!visit(supertype(t), s))
   927                         return false;
   928                     for (Type intf : interfaces(t)) {
   929                         if (!visit(intf, s))
   930                             return false;
   931                     }
   932                     return true;
   933                 }
   935                 if (s.isCompound()) {
   936                     // call recursively to reuse the above code
   937                     return visitClassType((ClassType)s, t);
   938                 }
   940                 if (s.tag == CLASS || s.tag == ARRAY) {
   941                     boolean upcast;
   942                     if ((upcast = isSubtype(erasure(t), erasure(s)))
   943                         || isSubtype(erasure(s), erasure(t))) {
   944                         if (!upcast && s.tag == ARRAY) {
   945                             if (!isReifiable(s))
   946                                 warnStack.head.warnUnchecked();
   947                             return true;
   948                         } else if (s.isRaw()) {
   949                             return true;
   950                         } else if (t.isRaw()) {
   951                             if (!isUnbounded(s))
   952                                 warnStack.head.warnUnchecked();
   953                             return true;
   954                         }
   955                         // Assume |a| <: |b|
   956                         final Type a = upcast ? t : s;
   957                         final Type b = upcast ? s : t;
   958                         final boolean HIGH = true;
   959                         final boolean LOW = false;
   960                         final boolean DONT_REWRITE_TYPEVARS = false;
   961                         Type aHigh = rewriteQuantifiers(a, HIGH, DONT_REWRITE_TYPEVARS);
   962                         Type aLow  = rewriteQuantifiers(a, LOW,  DONT_REWRITE_TYPEVARS);
   963                         Type bHigh = rewriteQuantifiers(b, HIGH, DONT_REWRITE_TYPEVARS);
   964                         Type bLow  = rewriteQuantifiers(b, LOW,  DONT_REWRITE_TYPEVARS);
   965                         Type lowSub = asSub(bLow, aLow.tsym);
   966                         Type highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym);
   967                         if (highSub == null) {
   968                             final boolean REWRITE_TYPEVARS = true;
   969                             aHigh = rewriteQuantifiers(a, HIGH, REWRITE_TYPEVARS);
   970                             aLow  = rewriteQuantifiers(a, LOW,  REWRITE_TYPEVARS);
   971                             bHigh = rewriteQuantifiers(b, HIGH, REWRITE_TYPEVARS);
   972                             bLow  = rewriteQuantifiers(b, LOW,  REWRITE_TYPEVARS);
   973                             lowSub = asSub(bLow, aLow.tsym);
   974                             highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym);
   975                         }
   976                         if (highSub != null) {
   977                             assert a.tsym == highSub.tsym && a.tsym == lowSub.tsym
   978                                 : a.tsym + " != " + highSub.tsym + " != " + lowSub.tsym;
   979                             if (!disjointTypes(aHigh.getTypeArguments(), highSub.getTypeArguments())
   980                                 && !disjointTypes(aHigh.getTypeArguments(), lowSub.getTypeArguments())
   981                                 && !disjointTypes(aLow.getTypeArguments(), highSub.getTypeArguments())
   982                                 && !disjointTypes(aLow.getTypeArguments(), lowSub.getTypeArguments())) {
   983                                 if (upcast ? giveWarning(a, highSub) || giveWarning(a, lowSub)
   984                                            : giveWarning(highSub, a) || giveWarning(lowSub, a))
   985                                     warnStack.head.warnUnchecked();
   986                                 return true;
   987                             }
   988                         }
   989                         if (isReifiable(s))
   990                             return isSubtypeUnchecked(a, b);
   991                         else
   992                             return isSubtypeUnchecked(a, b, warnStack.head);
   993                     }
   995                     // Sidecast
   996                     if (s.tag == CLASS) {
   997                         if ((s.tsym.flags() & INTERFACE) != 0) {
   998                             return ((t.tsym.flags() & FINAL) == 0)
   999                                 ? sideCast(t, s, warnStack.head)
  1000                                 : sideCastFinal(t, s, warnStack.head);
  1001                         } else if ((t.tsym.flags() & INTERFACE) != 0) {
  1002                             return ((s.tsym.flags() & FINAL) == 0)
  1003                                 ? sideCast(t, s, warnStack.head)
  1004                                 : sideCastFinal(t, s, warnStack.head);
  1005                         } else {
  1006                             // unrelated class types
  1007                             return false;
  1011                 return false;
  1014             @Override
  1015             public Boolean visitArrayType(ArrayType t, Type s) {
  1016                 switch (s.tag) {
  1017                 case ERROR:
  1018                 case BOT:
  1019                     return true;
  1020                 case TYPEVAR:
  1021                     if (isCastable(s, t, Warner.noWarnings)) {
  1022                         warnStack.head.warnUnchecked();
  1023                         return true;
  1024                     } else {
  1025                         return false;
  1027                 case CLASS:
  1028                     return isSubtype(t, s);
  1029                 case ARRAY:
  1030                     if (elemtype(t).tag <= lastBaseTag) {
  1031                         return elemtype(t).tag == elemtype(s).tag;
  1032                     } else {
  1033                         return visit(elemtype(t), elemtype(s));
  1035                 default:
  1036                     return false;
  1040             @Override
  1041             public Boolean visitTypeVar(TypeVar t, Type s) {
  1042                 switch (s.tag) {
  1043                 case ERROR:
  1044                 case BOT:
  1045                     return true;
  1046                 case TYPEVAR:
  1047                     if (isSubtype(t, s)) {
  1048                         return true;
  1049                     } else if (isCastable(t.bound, s, Warner.noWarnings)) {
  1050                         warnStack.head.warnUnchecked();
  1051                         return true;
  1052                     } else {
  1053                         return false;
  1055                 default:
  1056                     return isCastable(t.bound, s, warnStack.head);
  1060             @Override
  1061             public Boolean visitErrorType(ErrorType t, Type s) {
  1062                 return true;
  1064         };
  1065     // </editor-fold>
  1067     // <editor-fold defaultstate="collapsed" desc="disjointTypes">
  1068     public boolean disjointTypes(List<Type> ts, List<Type> ss) {
  1069         while (ts.tail != null && ss.tail != null) {
  1070             if (disjointType(ts.head, ss.head)) return true;
  1071             ts = ts.tail;
  1072             ss = ss.tail;
  1074         return false;
  1077     /**
  1078      * Two types or wildcards are considered disjoint if it can be
  1079      * proven that no type can be contained in both. It is
  1080      * conservative in that it is allowed to say that two types are
  1081      * not disjoint, even though they actually are.
  1083      * The type C<X> is castable to C<Y> exactly if X and Y are not
  1084      * disjoint.
  1085      */
  1086     public boolean disjointType(Type t, Type s) {
  1087         return disjointType.visit(t, s);
  1089     // where
  1090         private TypeRelation disjointType = new TypeRelation() {
  1092             private Set<TypePair> cache = new HashSet<TypePair>();
  1094             public Boolean visitType(Type t, Type s) {
  1095                 if (s.tag == WILDCARD)
  1096                     return visit(s, t);
  1097                 else
  1098                     return notSoftSubtypeRecursive(t, s) || notSoftSubtypeRecursive(s, t);
  1101             private boolean isCastableRecursive(Type t, Type s) {
  1102                 TypePair pair = new TypePair(t, s);
  1103                 if (cache.add(pair)) {
  1104                     try {
  1105                         return Types.this.isCastable(t, s);
  1106                     } finally {
  1107                         cache.remove(pair);
  1109                 } else {
  1110                     return true;
  1114             private boolean notSoftSubtypeRecursive(Type t, Type s) {
  1115                 TypePair pair = new TypePair(t, s);
  1116                 if (cache.add(pair)) {
  1117                     try {
  1118                         return Types.this.notSoftSubtype(t, s);
  1119                     } finally {
  1120                         cache.remove(pair);
  1122                 } else {
  1123                     return false;
  1127             @Override
  1128             public Boolean visitWildcardType(WildcardType t, Type s) {
  1129                 if (t.isUnbound())
  1130                     return false;
  1132                 if (s.tag != WILDCARD) {
  1133                     if (t.isExtendsBound())
  1134                         return notSoftSubtypeRecursive(s, t.type);
  1135                     else // isSuperBound()
  1136                         return notSoftSubtypeRecursive(t.type, s);
  1139                 if (s.isUnbound())
  1140                     return false;
  1142                 if (t.isExtendsBound()) {
  1143                     if (s.isExtendsBound())
  1144                         return !isCastableRecursive(t.type, upperBound(s));
  1145                     else if (s.isSuperBound())
  1146                         return notSoftSubtypeRecursive(lowerBound(s), t.type);
  1147                 } else if (t.isSuperBound()) {
  1148                     if (s.isExtendsBound())
  1149                         return notSoftSubtypeRecursive(t.type, upperBound(s));
  1151                 return false;
  1153         };
  1154     // </editor-fold>
  1156     // <editor-fold defaultstate="collapsed" desc="lowerBoundArgtypes">
  1157     /**
  1158      * Returns the lower bounds of the formals of a method.
  1159      */
  1160     public List<Type> lowerBoundArgtypes(Type t) {
  1161         return map(t.getParameterTypes(), lowerBoundMapping);
  1163     private final Mapping lowerBoundMapping = new Mapping("lowerBound") {
  1164             public Type apply(Type t) {
  1165                 return lowerBound(t);
  1167         };
  1168     // </editor-fold>
  1170     // <editor-fold defaultstate="collapsed" desc="notSoftSubtype">
  1171     /**
  1172      * This relation answers the question: is impossible that
  1173      * something of type `t' can be a subtype of `s'? This is
  1174      * different from the question "is `t' not a subtype of `s'?"
  1175      * when type variables are involved: Integer is not a subtype of T
  1176      * where <T extends Number> but it is not true that Integer cannot
  1177      * possibly be a subtype of T.
  1178      */
  1179     public boolean notSoftSubtype(Type t, Type s) {
  1180         if (t == s) return false;
  1181         if (t.tag == TYPEVAR) {
  1182             TypeVar tv = (TypeVar) t;
  1183             if (s.tag == TYPEVAR)
  1184                 s = s.getUpperBound();
  1185             return !isCastable(tv.bound,
  1186                                s,
  1187                                Warner.noWarnings);
  1189         if (s.tag != WILDCARD)
  1190             s = upperBound(s);
  1191         if (s.tag == TYPEVAR)
  1192             s = s.getUpperBound();
  1193         return !isSubtype(t, s);
  1195     // </editor-fold>
  1197     // <editor-fold defaultstate="collapsed" desc="isReifiable">
  1198     public boolean isReifiable(Type t) {
  1199         return isReifiable.visit(t);
  1201     // where
  1202         private UnaryVisitor<Boolean> isReifiable = new UnaryVisitor<Boolean>() {
  1204             public Boolean visitType(Type t, Void ignored) {
  1205                 return true;
  1208             @Override
  1209             public Boolean visitClassType(ClassType t, Void ignored) {
  1210                 if (!t.isParameterized())
  1211                     return true;
  1213                 for (Type param : t.allparams()) {
  1214                     if (!param.isUnbound())
  1215                         return false;
  1217                 return true;
  1220             @Override
  1221             public Boolean visitArrayType(ArrayType t, Void ignored) {
  1222                 return visit(t.elemtype);
  1225             @Override
  1226             public Boolean visitTypeVar(TypeVar t, Void ignored) {
  1227                 return false;
  1229         };
  1230     // </editor-fold>
  1232     // <editor-fold defaultstate="collapsed" desc="Array Utils">
  1233     public boolean isArray(Type t) {
  1234         while (t.tag == WILDCARD)
  1235             t = upperBound(t);
  1236         return t.tag == ARRAY;
  1239     /**
  1240      * The element type of an array.
  1241      */
  1242     public Type elemtype(Type t) {
  1243         switch (t.tag) {
  1244         case WILDCARD:
  1245             return elemtype(upperBound(t));
  1246         case ARRAY:
  1247             return ((ArrayType)t).elemtype;
  1248         case FORALL:
  1249             return elemtype(((ForAll)t).qtype);
  1250         case ERROR:
  1251             return t;
  1252         default:
  1253             return null;
  1257     /**
  1258      * Mapping to take element type of an arraytype
  1259      */
  1260     private Mapping elemTypeFun = new Mapping ("elemTypeFun") {
  1261         public Type apply(Type t) { return elemtype(t); }
  1262     };
  1264     /**
  1265      * The number of dimensions of an array type.
  1266      */
  1267     public int dimensions(Type t) {
  1268         int result = 0;
  1269         while (t.tag == ARRAY) {
  1270             result++;
  1271             t = elemtype(t);
  1273         return result;
  1275     // </editor-fold>
  1277     // <editor-fold defaultstate="collapsed" desc="asSuper">
  1278     /**
  1279      * Return the (most specific) base type of t that starts with the
  1280      * given symbol.  If none exists, return null.
  1282      * @param t a type
  1283      * @param sym a symbol
  1284      */
  1285     public Type asSuper(Type t, Symbol sym) {
  1286         return asSuper.visit(t, sym);
  1288     // where
  1289         private SimpleVisitor<Type,Symbol> asSuper = new SimpleVisitor<Type,Symbol>() {
  1291             public Type visitType(Type t, Symbol sym) {
  1292                 return null;
  1295             @Override
  1296             public Type visitClassType(ClassType t, Symbol sym) {
  1297                 if (t.tsym == sym)
  1298                     return t;
  1300                 Type st = supertype(t);
  1301                 if (st.tag == CLASS || st.tag == TYPEVAR || st.tag == ERROR) {
  1302                     Type x = asSuper(st, sym);
  1303                     if (x != null)
  1304                         return x;
  1306                 if ((sym.flags() & INTERFACE) != 0) {
  1307                     for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
  1308                         Type x = asSuper(l.head, sym);
  1309                         if (x != null)
  1310                             return x;
  1313                 return null;
  1316             @Override
  1317             public Type visitArrayType(ArrayType t, Symbol sym) {
  1318                 return isSubtype(t, sym.type) ? sym.type : null;
  1321             @Override
  1322             public Type visitTypeVar(TypeVar t, Symbol sym) {
  1323                 if (t.tsym == sym)
  1324                     return t;
  1325                 else
  1326                     return asSuper(t.bound, sym);
  1329             @Override
  1330             public Type visitErrorType(ErrorType t, Symbol sym) {
  1331                 return t;
  1333         };
  1335     /**
  1336      * Return the base type of t or any of its outer types that starts
  1337      * with the given symbol.  If none exists, return null.
  1339      * @param t a type
  1340      * @param sym a symbol
  1341      */
  1342     public Type asOuterSuper(Type t, Symbol sym) {
  1343         switch (t.tag) {
  1344         case CLASS:
  1345             do {
  1346                 Type s = asSuper(t, sym);
  1347                 if (s != null) return s;
  1348                 t = t.getEnclosingType();
  1349             } while (t.tag == CLASS);
  1350             return null;
  1351         case ARRAY:
  1352             return isSubtype(t, sym.type) ? sym.type : null;
  1353         case TYPEVAR:
  1354             return asSuper(t, sym);
  1355         case ERROR:
  1356             return t;
  1357         default:
  1358             return null;
  1362     /**
  1363      * Return the base type of t or any of its enclosing types that
  1364      * starts with the given symbol.  If none exists, return null.
  1366      * @param t a type
  1367      * @param sym a symbol
  1368      */
  1369     public Type asEnclosingSuper(Type t, Symbol sym) {
  1370         switch (t.tag) {
  1371         case CLASS:
  1372             do {
  1373                 Type s = asSuper(t, sym);
  1374                 if (s != null) return s;
  1375                 Type outer = t.getEnclosingType();
  1376                 t = (outer.tag == CLASS) ? outer :
  1377                     (t.tsym.owner.enclClass() != null) ? t.tsym.owner.enclClass().type :
  1378                     Type.noType;
  1379             } while (t.tag == CLASS);
  1380             return null;
  1381         case ARRAY:
  1382             return isSubtype(t, sym.type) ? sym.type : null;
  1383         case TYPEVAR:
  1384             return asSuper(t, sym);
  1385         case ERROR:
  1386             return t;
  1387         default:
  1388             return null;
  1391     // </editor-fold>
  1393     // <editor-fold defaultstate="collapsed" desc="memberType">
  1394     /**
  1395      * The type of given symbol, seen as a member of t.
  1397      * @param t a type
  1398      * @param sym a symbol
  1399      */
  1400     public Type memberType(Type t, Symbol sym) {
  1401         return (sym.flags() & STATIC) != 0
  1402             ? sym.type
  1403             : memberType.visit(t, sym);
  1405     // where
  1406         private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
  1408             public Type visitType(Type t, Symbol sym) {
  1409                 return sym.type;
  1412             @Override
  1413             public Type visitWildcardType(WildcardType t, Symbol sym) {
  1414                 return memberType(upperBound(t), sym);
  1417             @Override
  1418             public Type visitClassType(ClassType t, Symbol sym) {
  1419                 Symbol owner = sym.owner;
  1420                 long flags = sym.flags();
  1421                 if (((flags & STATIC) == 0) && owner.type.isParameterized()) {
  1422                     Type base = asOuterSuper(t, owner);
  1423                     if (base != null) {
  1424                         List<Type> ownerParams = owner.type.allparams();
  1425                         List<Type> baseParams = base.allparams();
  1426                         if (ownerParams.nonEmpty()) {
  1427                             if (baseParams.isEmpty()) {
  1428                                 // then base is a raw type
  1429                                 return erasure(sym.type);
  1430                             } else {
  1431                                 return subst(sym.type, ownerParams, baseParams);
  1436                 return sym.type;
  1439             @Override
  1440             public Type visitTypeVar(TypeVar t, Symbol sym) {
  1441                 return memberType(t.bound, sym);
  1444             @Override
  1445             public Type visitErrorType(ErrorType t, Symbol sym) {
  1446                 return t;
  1448         };
  1449     // </editor-fold>
  1451     // <editor-fold defaultstate="collapsed" desc="isAssignable">
  1452     public boolean isAssignable(Type t, Type s) {
  1453         return isAssignable(t, s, Warner.noWarnings);
  1456     /**
  1457      * Is t assignable to s?<br>
  1458      * Equivalent to subtype except for constant values and raw
  1459      * types.<br>
  1460      * (not defined for Method and ForAll types)
  1461      */
  1462     public boolean isAssignable(Type t, Type s, Warner warn) {
  1463         if (t.tag == ERROR)
  1464             return true;
  1465         if (t.tag <= INT && t.constValue() != null) {
  1466             int value = ((Number)t.constValue()).intValue();
  1467             switch (s.tag) {
  1468             case BYTE:
  1469                 if (Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE)
  1470                     return true;
  1471                 break;
  1472             case CHAR:
  1473                 if (Character.MIN_VALUE <= value && value <= Character.MAX_VALUE)
  1474                     return true;
  1475                 break;
  1476             case SHORT:
  1477                 if (Short.MIN_VALUE <= value && value <= Short.MAX_VALUE)
  1478                     return true;
  1479                 break;
  1480             case INT:
  1481                 return true;
  1482             case CLASS:
  1483                 switch (unboxedType(s).tag) {
  1484                 case BYTE:
  1485                 case CHAR:
  1486                 case SHORT:
  1487                     return isAssignable(t, unboxedType(s), warn);
  1489                 break;
  1492         return isConvertible(t, s, warn);
  1494     // </editor-fold>
  1496     // <editor-fold defaultstate="collapsed" desc="erasure">
  1497     /**
  1498      * The erasure of t {@code |t|} -- the type that results when all
  1499      * type parameters in t are deleted.
  1500      */
  1501     public Type erasure(Type t) {
  1502         if (t.tag <= lastBaseTag)
  1503             return t; /* fast special case */
  1504         else
  1505             return erasure.visit(t);
  1507     // where
  1508         private UnaryVisitor<Type> erasure = new UnaryVisitor<Type>() {
  1509             public Type visitType(Type t, Void ignored) {
  1510                 if (t.tag <= lastBaseTag)
  1511                     return t; /*fast special case*/
  1512                 else
  1513                     return t.map(erasureFun);
  1516             @Override
  1517             public Type visitWildcardType(WildcardType t, Void ignored) {
  1518                 return erasure(upperBound(t));
  1521             @Override
  1522             public Type visitClassType(ClassType t, Void ignored) {
  1523                 return t.tsym.erasure(Types.this);
  1526             @Override
  1527             public Type visitTypeVar(TypeVar t, Void ignored) {
  1528                 return erasure(t.bound);
  1531             @Override
  1532             public Type visitErrorType(ErrorType t, Void ignored) {
  1533                 return t;
  1535         };
  1536     private Mapping erasureFun = new Mapping ("erasure") {
  1537             public Type apply(Type t) { return erasure(t); }
  1538         };
  1540     public List<Type> erasure(List<Type> ts) {
  1541         return Type.map(ts, erasureFun);
  1543     // </editor-fold>
  1545     // <editor-fold defaultstate="collapsed" desc="makeCompoundType">
  1546     /**
  1547      * Make a compound type from non-empty list of types
  1549      * @param bounds            the types from which the compound type is formed
  1550      * @param supertype         is objectType if all bounds are interfaces,
  1551      *                          null otherwise.
  1552      */
  1553     public Type makeCompoundType(List<Type> bounds,
  1554                                  Type supertype) {
  1555         ClassSymbol bc =
  1556             new ClassSymbol(ABSTRACT|PUBLIC|SYNTHETIC|COMPOUND|ACYCLIC,
  1557                             Type.moreInfo
  1558                                 ? names.fromString(bounds.toString())
  1559                                 : names.empty,
  1560                             syms.noSymbol);
  1561         if (bounds.head.tag == TYPEVAR)
  1562             // error condition, recover
  1563             bc.erasure_field = syms.objectType;
  1564         else
  1565             bc.erasure_field = erasure(bounds.head);
  1566         bc.members_field = new Scope(bc);
  1567         ClassType bt = (ClassType)bc.type;
  1568         bt.allparams_field = List.nil();
  1569         if (supertype != null) {
  1570             bt.supertype_field = supertype;
  1571             bt.interfaces_field = bounds;
  1572         } else {
  1573             bt.supertype_field = bounds.head;
  1574             bt.interfaces_field = bounds.tail;
  1576         assert bt.supertype_field.tsym.completer != null
  1577             || !bt.supertype_field.isInterface()
  1578             : bt.supertype_field;
  1579         return bt;
  1582     /**
  1583      * Same as {@link #makeCompoundType(List,Type)}, except that the
  1584      * second parameter is computed directly. Note that this might
  1585      * cause a symbol completion.  Hence, this version of
  1586      * makeCompoundType may not be called during a classfile read.
  1587      */
  1588     public Type makeCompoundType(List<Type> bounds) {
  1589         Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ?
  1590             supertype(bounds.head) : null;
  1591         return makeCompoundType(bounds, supertype);
  1594     /**
  1595      * A convenience wrapper for {@link #makeCompoundType(List)}; the
  1596      * arguments are converted to a list and passed to the other
  1597      * method.  Note that this might cause a symbol completion.
  1598      * Hence, this version of makeCompoundType may not be called
  1599      * during a classfile read.
  1600      */
  1601     public Type makeCompoundType(Type bound1, Type bound2) {
  1602         return makeCompoundType(List.of(bound1, bound2));
  1604     // </editor-fold>
  1606     // <editor-fold defaultstate="collapsed" desc="supertype">
  1607     public Type supertype(Type t) {
  1608         return supertype.visit(t);
  1610     // where
  1611         private UnaryVisitor<Type> supertype = new UnaryVisitor<Type>() {
  1613             public Type visitType(Type t, Void ignored) {
  1614                 // A note on wildcards: there is no good way to
  1615                 // determine a supertype for a super bounded wildcard.
  1616                 return null;
  1619             @Override
  1620             public Type visitClassType(ClassType t, Void ignored) {
  1621                 if (t.supertype_field == null) {
  1622                     Type supertype = ((ClassSymbol)t.tsym).getSuperclass();
  1623                     // An interface has no superclass; its supertype is Object.
  1624                     if (t.isInterface())
  1625                         supertype = ((ClassType)t.tsym.type).supertype_field;
  1626                     if (t.supertype_field == null) {
  1627                         List<Type> actuals = classBound(t).allparams();
  1628                         List<Type> formals = t.tsym.type.allparams();
  1629                         if (actuals.isEmpty()) {
  1630                             if (formals.isEmpty())
  1631                                 // Should not happen.  See comments below in interfaces
  1632                                 t.supertype_field = supertype;
  1633                             else
  1634                                 t.supertype_field = erasure(supertype);
  1635                         } else {
  1636                             t.supertype_field = subst(supertype, formals, actuals);
  1640                 return t.supertype_field;
  1643             /**
  1644              * The supertype is always a class type. If the type
  1645              * variable's bounds start with a class type, this is also
  1646              * the supertype.  Otherwise, the supertype is
  1647              * java.lang.Object.
  1648              */
  1649             @Override
  1650             public Type visitTypeVar(TypeVar t, Void ignored) {
  1651                 if (t.bound.tag == TYPEVAR ||
  1652                     (!t.bound.isCompound() && !t.bound.isInterface())) {
  1653                     return t.bound;
  1654                 } else {
  1655                     return supertype(t.bound);
  1659             @Override
  1660             public Type visitArrayType(ArrayType t, Void ignored) {
  1661                 if (t.elemtype.isPrimitive() || isSameType(t.elemtype, syms.objectType))
  1662                     return arraySuperType();
  1663                 else
  1664                     return new ArrayType(supertype(t.elemtype), t.tsym);
  1667             @Override
  1668             public Type visitErrorType(ErrorType t, Void ignored) {
  1669                 return t;
  1671         };
  1672     // </editor-fold>
  1674     // <editor-fold defaultstate="collapsed" desc="interfaces">
  1675     /**
  1676      * Return the interfaces implemented by this class.
  1677      */
  1678     public List<Type> interfaces(Type t) {
  1679         return interfaces.visit(t);
  1681     // where
  1682         private UnaryVisitor<List<Type>> interfaces = new UnaryVisitor<List<Type>>() {
  1684             public List<Type> visitType(Type t, Void ignored) {
  1685                 return List.nil();
  1688             @Override
  1689             public List<Type> visitClassType(ClassType t, Void ignored) {
  1690                 if (t.interfaces_field == null) {
  1691                     List<Type> interfaces = ((ClassSymbol)t.tsym).getInterfaces();
  1692                     if (t.interfaces_field == null) {
  1693                         // If t.interfaces_field is null, then t must
  1694                         // be a parameterized type (not to be confused
  1695                         // with a generic type declaration).
  1696                         // Terminology:
  1697                         //    Parameterized type: List<String>
  1698                         //    Generic type declaration: class List<E> { ... }
  1699                         // So t corresponds to List<String> and
  1700                         // t.tsym.type corresponds to List<E>.
  1701                         // The reason t must be parameterized type is
  1702                         // that completion will happen as a side
  1703                         // effect of calling
  1704                         // ClassSymbol.getInterfaces.  Since
  1705                         // t.interfaces_field is null after
  1706                         // completion, we can assume that t is not the
  1707                         // type of a class/interface declaration.
  1708                         assert t != t.tsym.type : t.toString();
  1709                         List<Type> actuals = t.allparams();
  1710                         List<Type> formals = t.tsym.type.allparams();
  1711                         if (actuals.isEmpty()) {
  1712                             if (formals.isEmpty()) {
  1713                                 // In this case t is not generic (nor raw).
  1714                                 // So this should not happen.
  1715                                 t.interfaces_field = interfaces;
  1716                             } else {
  1717                                 t.interfaces_field = erasure(interfaces);
  1719                         } else {
  1720                             t.interfaces_field =
  1721                                 upperBounds(subst(interfaces, formals, actuals));
  1725                 return t.interfaces_field;
  1728             @Override
  1729             public List<Type> visitTypeVar(TypeVar t, Void ignored) {
  1730                 if (t.bound.isCompound())
  1731                     return interfaces(t.bound);
  1733                 if (t.bound.isInterface())
  1734                     return List.of(t.bound);
  1736                 return List.nil();
  1738         };
  1739     // </editor-fold>
  1741     // <editor-fold defaultstate="collapsed" desc="isDerivedRaw">
  1742     Map<Type,Boolean> isDerivedRawCache = new HashMap<Type,Boolean>();
  1744     public boolean isDerivedRaw(Type t) {
  1745         Boolean result = isDerivedRawCache.get(t);
  1746         if (result == null) {
  1747             result = isDerivedRawInternal(t);
  1748             isDerivedRawCache.put(t, result);
  1750         return result;
  1753     public boolean isDerivedRawInternal(Type t) {
  1754         if (t.isErroneous())
  1755             return false;
  1756         return
  1757             t.isRaw() ||
  1758             supertype(t) != null && isDerivedRaw(supertype(t)) ||
  1759             isDerivedRaw(interfaces(t));
  1762     public boolean isDerivedRaw(List<Type> ts) {
  1763         List<Type> l = ts;
  1764         while (l.nonEmpty() && !isDerivedRaw(l.head)) l = l.tail;
  1765         return l.nonEmpty();
  1767     // </editor-fold>
  1769     // <editor-fold defaultstate="collapsed" desc="setBounds">
  1770     /**
  1771      * Set the bounds field of the given type variable to reflect a
  1772      * (possibly multiple) list of bounds.
  1773      * @param t                 a type variable
  1774      * @param bounds            the bounds, must be nonempty
  1775      * @param supertype         is objectType if all bounds are interfaces,
  1776      *                          null otherwise.
  1777      */
  1778     public void setBounds(TypeVar t, List<Type> bounds, Type supertype) {
  1779         if (bounds.tail.isEmpty())
  1780             t.bound = bounds.head;
  1781         else
  1782             t.bound = makeCompoundType(bounds, supertype);
  1783         t.rank_field = -1;
  1786     /**
  1787      * Same as {@link #setBounds(Type.TypeVar,List,Type)}, except that
  1788      * third parameter is computed directly.  Note that this test
  1789      * might cause a symbol completion.  Hence, this version of
  1790      * setBounds may not be called during a classfile read.
  1791      */
  1792     public void setBounds(TypeVar t, List<Type> bounds) {
  1793         Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ?
  1794             supertype(bounds.head) : null;
  1795         setBounds(t, bounds, supertype);
  1796         t.rank_field = -1;
  1798     // </editor-fold>
  1800     // <editor-fold defaultstate="collapsed" desc="getBounds">
  1801     /**
  1802      * Return list of bounds of the given type variable.
  1803      */
  1804     public List<Type> getBounds(TypeVar t) {
  1805         if (t.bound.isErroneous() || !t.bound.isCompound())
  1806             return List.of(t.bound);
  1807         else if ((erasure(t).tsym.flags() & INTERFACE) == 0)
  1808             return interfaces(t).prepend(supertype(t));
  1809         else
  1810             // No superclass was given in bounds.
  1811             // In this case, supertype is Object, erasure is first interface.
  1812             return interfaces(t);
  1814     // </editor-fold>
  1816     // <editor-fold defaultstate="collapsed" desc="classBound">
  1817     /**
  1818      * If the given type is a (possibly selected) type variable,
  1819      * return the bounding class of this type, otherwise return the
  1820      * type itself.
  1821      */
  1822     public Type classBound(Type t) {
  1823         return classBound.visit(t);
  1825     // where
  1826         private UnaryVisitor<Type> classBound = new UnaryVisitor<Type>() {
  1828             public Type visitType(Type t, Void ignored) {
  1829                 return t;
  1832             @Override
  1833             public Type visitClassType(ClassType t, Void ignored) {
  1834                 Type outer1 = classBound(t.getEnclosingType());
  1835                 if (outer1 != t.getEnclosingType())
  1836                     return new ClassType(outer1, t.getTypeArguments(), t.tsym);
  1837                 else
  1838                     return t;
  1841             @Override
  1842             public Type visitTypeVar(TypeVar t, Void ignored) {
  1843                 return classBound(supertype(t));
  1846             @Override
  1847             public Type visitErrorType(ErrorType t, Void ignored) {
  1848                 return t;
  1850         };
  1851     // </editor-fold>
  1853     // <editor-fold defaultstate="collapsed" desc="sub signature / override equivalence">
  1854     /**
  1855      * Returns true iff the first signature is a <em>sub
  1856      * signature</em> of the other.  This is <b>not</b> an equivalence
  1857      * relation.
  1859      * @see "The Java Language Specification, Third Ed. (8.4.2)."
  1860      * @see #overrideEquivalent(Type t, Type s)
  1861      * @param t first signature (possibly raw).
  1862      * @param s second signature (could be subjected to erasure).
  1863      * @return true if t is a sub signature of s.
  1864      */
  1865     public boolean isSubSignature(Type t, Type s) {
  1866         return hasSameArgs(t, s) || hasSameArgs(t, erasure(s));
  1869     /**
  1870      * Returns true iff these signatures are related by <em>override
  1871      * equivalence</em>.  This is the natural extension of
  1872      * isSubSignature to an equivalence relation.
  1874      * @see "The Java Language Specification, Third Ed. (8.4.2)."
  1875      * @see #isSubSignature(Type t, Type s)
  1876      * @param t a signature (possible raw, could be subjected to
  1877      * erasure).
  1878      * @param s a signature (possible raw, could be subjected to
  1879      * erasure).
  1880      * @return true if either argument is a sub signature of the other.
  1881      */
  1882     public boolean overrideEquivalent(Type t, Type s) {
  1883         return hasSameArgs(t, s) ||
  1884             hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s);
  1887     /**
  1888      * Does t have the same arguments as s?  It is assumed that both
  1889      * types are (possibly polymorphic) method types.  Monomorphic
  1890      * method types "have the same arguments", if their argument lists
  1891      * are equal.  Polymorphic method types "have the same arguments",
  1892      * if they have the same arguments after renaming all type
  1893      * variables of one to corresponding type variables in the other,
  1894      * where correspondence is by position in the type parameter list.
  1895      */
  1896     public boolean hasSameArgs(Type t, Type s) {
  1897         return hasSameArgs.visit(t, s);
  1899     // where
  1900         private TypeRelation hasSameArgs = new TypeRelation() {
  1902             public Boolean visitType(Type t, Type s) {
  1903                 throw new AssertionError();
  1906             @Override
  1907             public Boolean visitMethodType(MethodType t, Type s) {
  1908                 return s.tag == METHOD
  1909                     && containsTypeEquivalent(t.argtypes, s.getParameterTypes());
  1912             @Override
  1913             public Boolean visitForAll(ForAll t, Type s) {
  1914                 if (s.tag != FORALL)
  1915                     return false;
  1917                 ForAll forAll = (ForAll)s;
  1918                 return hasSameBounds(t, forAll)
  1919                     && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
  1922             @Override
  1923             public Boolean visitErrorType(ErrorType t, Type s) {
  1924                 return false;
  1926         };
  1927     // </editor-fold>
  1929     // <editor-fold defaultstate="collapsed" desc="subst">
  1930     public List<Type> subst(List<Type> ts,
  1931                             List<Type> from,
  1932                             List<Type> to) {
  1933         return new Subst(from, to).subst(ts);
  1936     /**
  1937      * Substitute all occurrences of a type in `from' with the
  1938      * corresponding type in `to' in 't'. Match lists `from' and `to'
  1939      * from the right: If lists have different length, discard leading
  1940      * elements of the longer list.
  1941      */
  1942     public Type subst(Type t, List<Type> from, List<Type> to) {
  1943         return new Subst(from, to).subst(t);
  1946     private class Subst extends UnaryVisitor<Type> {
  1947         List<Type> from;
  1948         List<Type> to;
  1950         public Subst(List<Type> from, List<Type> to) {
  1951             int fromLength = from.length();
  1952             int toLength = to.length();
  1953             while (fromLength > toLength) {
  1954                 fromLength--;
  1955                 from = from.tail;
  1957             while (fromLength < toLength) {
  1958                 toLength--;
  1959                 to = to.tail;
  1961             this.from = from;
  1962             this.to = to;
  1965         Type subst(Type t) {
  1966             if (from.tail == null)
  1967                 return t;
  1968             else
  1969                 return visit(t);
  1972         List<Type> subst(List<Type> ts) {
  1973             if (from.tail == null)
  1974                 return ts;
  1975             boolean wild = false;
  1976             if (ts.nonEmpty() && from.nonEmpty()) {
  1977                 Type head1 = subst(ts.head);
  1978                 List<Type> tail1 = subst(ts.tail);
  1979                 if (head1 != ts.head || tail1 != ts.tail)
  1980                     return tail1.prepend(head1);
  1982             return ts;
  1985         public Type visitType(Type t, Void ignored) {
  1986             return t;
  1989         @Override
  1990         public Type visitMethodType(MethodType t, Void ignored) {
  1991             List<Type> argtypes = subst(t.argtypes);
  1992             Type restype = subst(t.restype);
  1993             List<Type> thrown = subst(t.thrown);
  1994             if (argtypes == t.argtypes &&
  1995                 restype == t.restype &&
  1996                 thrown == t.thrown)
  1997                 return t;
  1998             else
  1999                 return new MethodType(argtypes, restype, thrown, t.tsym);
  2002         @Override
  2003         public Type visitTypeVar(TypeVar t, Void ignored) {
  2004             for (List<Type> from = this.from, to = this.to;
  2005                  from.nonEmpty();
  2006                  from = from.tail, to = to.tail) {
  2007                 if (t == from.head) {
  2008                     return to.head.withTypeVar(t);
  2011             return t;
  2014         @Override
  2015         public Type visitClassType(ClassType t, Void ignored) {
  2016             if (!t.isCompound()) {
  2017                 List<Type> typarams = t.getTypeArguments();
  2018                 List<Type> typarams1 = subst(typarams);
  2019                 Type outer = t.getEnclosingType();
  2020                 Type outer1 = subst(outer);
  2021                 if (typarams1 == typarams && outer1 == outer)
  2022                     return t;
  2023                 else
  2024                     return new ClassType(outer1, typarams1, t.tsym);
  2025             } else {
  2026                 Type st = subst(supertype(t));
  2027                 List<Type> is = upperBounds(subst(interfaces(t)));
  2028                 if (st == supertype(t) && is == interfaces(t))
  2029                     return t;
  2030                 else
  2031                     return makeCompoundType(is.prepend(st));
  2035         @Override
  2036         public Type visitWildcardType(WildcardType t, Void ignored) {
  2037             Type bound = t.type;
  2038             if (t.kind != BoundKind.UNBOUND)
  2039                 bound = subst(bound);
  2040             if (bound == t.type) {
  2041                 return t;
  2042             } else {
  2043                 if (t.isExtendsBound() && bound.isExtendsBound())
  2044                     bound = upperBound(bound);
  2045                 return new WildcardType(bound, t.kind, syms.boundClass, t.bound);
  2049         @Override
  2050         public Type visitArrayType(ArrayType t, Void ignored) {
  2051             Type elemtype = subst(t.elemtype);
  2052             if (elemtype == t.elemtype)
  2053                 return t;
  2054             else
  2055                 return new ArrayType(upperBound(elemtype), t.tsym);
  2058         @Override
  2059         public Type visitForAll(ForAll t, Void ignored) {
  2060             List<Type> tvars1 = substBounds(t.tvars, from, to);
  2061             Type qtype1 = subst(t.qtype);
  2062             if (tvars1 == t.tvars && qtype1 == t.qtype) {
  2063                 return t;
  2064             } else if (tvars1 == t.tvars) {
  2065                 return new ForAll(tvars1, qtype1);
  2066             } else {
  2067                 return new ForAll(tvars1, Types.this.subst(qtype1, t.tvars, tvars1));
  2071         @Override
  2072         public Type visitErrorType(ErrorType t, Void ignored) {
  2073             return t;
  2077     public List<Type> substBounds(List<Type> tvars,
  2078                                   List<Type> from,
  2079                                   List<Type> to) {
  2080         if (tvars.isEmpty())
  2081             return tvars;
  2082         if (tvars.tail.isEmpty())
  2083             // fast common case
  2084             return List.<Type>of(substBound((TypeVar)tvars.head, from, to));
  2085         ListBuffer<Type> newBoundsBuf = lb();
  2086         boolean changed = false;
  2087         // calculate new bounds
  2088         for (Type t : tvars) {
  2089             TypeVar tv = (TypeVar) t;
  2090             Type bound = subst(tv.bound, from, to);
  2091             if (bound != tv.bound)
  2092                 changed = true;
  2093             newBoundsBuf.append(bound);
  2095         if (!changed)
  2096             return tvars;
  2097         ListBuffer<Type> newTvars = lb();
  2098         // create new type variables without bounds
  2099         for (Type t : tvars) {
  2100             newTvars.append(new TypeVar(t.tsym, null, syms.botType));
  2102         // the new bounds should use the new type variables in place
  2103         // of the old
  2104         List<Type> newBounds = newBoundsBuf.toList();
  2105         from = tvars;
  2106         to = newTvars.toList();
  2107         for (; !newBounds.isEmpty(); newBounds = newBounds.tail) {
  2108             newBounds.head = subst(newBounds.head, from, to);
  2110         newBounds = newBoundsBuf.toList();
  2111         // set the bounds of new type variables to the new bounds
  2112         for (Type t : newTvars.toList()) {
  2113             TypeVar tv = (TypeVar) t;
  2114             tv.bound = newBounds.head;
  2115             newBounds = newBounds.tail;
  2117         return newTvars.toList();
  2120     public TypeVar substBound(TypeVar t, List<Type> from, List<Type> to) {
  2121         Type bound1 = subst(t.bound, from, to);
  2122         if (bound1 == t.bound)
  2123             return t;
  2124         else
  2125             return new TypeVar(t.tsym, bound1, syms.botType);
  2127     // </editor-fold>
  2129     // <editor-fold defaultstate="collapsed" desc="hasSameBounds">
  2130     /**
  2131      * Does t have the same bounds for quantified variables as s?
  2132      */
  2133     boolean hasSameBounds(ForAll t, ForAll s) {
  2134         List<Type> l1 = t.tvars;
  2135         List<Type> l2 = s.tvars;
  2136         while (l1.nonEmpty() && l2.nonEmpty() &&
  2137                isSameType(l1.head.getUpperBound(),
  2138                           subst(l2.head.getUpperBound(),
  2139                                 s.tvars,
  2140                                 t.tvars))) {
  2141             l1 = l1.tail;
  2142             l2 = l2.tail;
  2144         return l1.isEmpty() && l2.isEmpty();
  2146     // </editor-fold>
  2148     // <editor-fold defaultstate="collapsed" desc="newInstances">
  2149     /** Create new vector of type variables from list of variables
  2150      *  changing all recursive bounds from old to new list.
  2151      */
  2152     public List<Type> newInstances(List<Type> tvars) {
  2153         List<Type> tvars1 = Type.map(tvars, newInstanceFun);
  2154         for (List<Type> l = tvars1; l.nonEmpty(); l = l.tail) {
  2155             TypeVar tv = (TypeVar) l.head;
  2156             tv.bound = subst(tv.bound, tvars, tvars1);
  2158         return tvars1;
  2160     static private Mapping newInstanceFun = new Mapping("newInstanceFun") {
  2161             public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound()); }
  2162         };
  2163     // </editor-fold>
  2165     // <editor-fold defaultstate="collapsed" desc="rank">
  2166     /**
  2167      * The rank of a class is the length of the longest path between
  2168      * the class and java.lang.Object in the class inheritance
  2169      * graph. Undefined for all but reference types.
  2170      */
  2171     public int rank(Type t) {
  2172         switch(t.tag) {
  2173         case CLASS: {
  2174             ClassType cls = (ClassType)t;
  2175             if (cls.rank_field < 0) {
  2176                 Name fullname = cls.tsym.getQualifiedName();
  2177                 if (fullname == fullname.table.java_lang_Object)
  2178                     cls.rank_field = 0;
  2179                 else {
  2180                     int r = rank(supertype(cls));
  2181                     for (List<Type> l = interfaces(cls);
  2182                          l.nonEmpty();
  2183                          l = l.tail) {
  2184                         if (rank(l.head) > r)
  2185                             r = rank(l.head);
  2187                     cls.rank_field = r + 1;
  2190             return cls.rank_field;
  2192         case TYPEVAR: {
  2193             TypeVar tvar = (TypeVar)t;
  2194             if (tvar.rank_field < 0) {
  2195                 int r = rank(supertype(tvar));
  2196                 for (List<Type> l = interfaces(tvar);
  2197                      l.nonEmpty();
  2198                      l = l.tail) {
  2199                     if (rank(l.head) > r) r = rank(l.head);
  2201                 tvar.rank_field = r + 1;
  2203             return tvar.rank_field;
  2205         case ERROR:
  2206             return 0;
  2207         default:
  2208             throw new AssertionError();
  2211     // </editor-fold>
  2213     // <editor-fold defaultstate="collapsed" desc="toString">
  2214     /**
  2215      * This toString is slightly more descriptive than the one on Type.
  2216      */
  2217     public String toString(Type t) {
  2218         if (t.tag == FORALL) {
  2219             ForAll forAll = (ForAll)t;
  2220             return typaramsString(forAll.tvars) + forAll.qtype;
  2222         return "" + t;
  2224     // where
  2225         private String typaramsString(List<Type> tvars) {
  2226             StringBuffer s = new StringBuffer();
  2227             s.append('<');
  2228             boolean first = true;
  2229             for (Type t : tvars) {
  2230                 if (!first) s.append(", ");
  2231                 first = false;
  2232                 appendTyparamString(((TypeVar)t), s);
  2234             s.append('>');
  2235             return s.toString();
  2237         private void appendTyparamString(TypeVar t, StringBuffer buf) {
  2238             buf.append(t);
  2239             if (t.bound == null ||
  2240                 t.bound.tsym.getQualifiedName() == names.java_lang_Object)
  2241                 return;
  2242             buf.append(" extends "); // Java syntax; no need for i18n
  2243             Type bound = t.bound;
  2244             if (!bound.isCompound()) {
  2245                 buf.append(bound);
  2246             } else if ((erasure(t).tsym.flags() & INTERFACE) == 0) {
  2247                 buf.append(supertype(t));
  2248                 for (Type intf : interfaces(t)) {
  2249                     buf.append('&');
  2250                     buf.append(intf);
  2252             } else {
  2253                 // No superclass was given in bounds.
  2254                 // In this case, supertype is Object, erasure is first interface.
  2255                 boolean first = true;
  2256                 for (Type intf : interfaces(t)) {
  2257                     if (!first) buf.append('&');
  2258                     first = false;
  2259                     buf.append(intf);
  2263     // </editor-fold>
  2265     // <editor-fold defaultstate="collapsed" desc="Determining least upper bounds of types">
  2266     /**
  2267      * A cache for closures.
  2269      * <p>A closure is a list of all the supertypes and interfaces of
  2270      * a class or interface type, ordered by ClassSymbol.precedes
  2271      * (that is, subclasses come first, arbitrary but fixed
  2272      * otherwise).
  2273      */
  2274     private Map<Type,List<Type>> closureCache = new HashMap<Type,List<Type>>();
  2276     /**
  2277      * Returns the closure of a class or interface type.
  2278      */
  2279     public List<Type> closure(Type t) {
  2280         List<Type> cl = closureCache.get(t);
  2281         if (cl == null) {
  2282             Type st = supertype(t);
  2283             if (!t.isCompound()) {
  2284                 if (st.tag == CLASS) {
  2285                     cl = insert(closure(st), t);
  2286                 } else if (st.tag == TYPEVAR) {
  2287                     cl = closure(st).prepend(t);
  2288                 } else {
  2289                     cl = List.of(t);
  2291             } else {
  2292                 cl = closure(supertype(t));
  2294             for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail)
  2295                 cl = union(cl, closure(l.head));
  2296             closureCache.put(t, cl);
  2298         return cl;
  2301     /**
  2302      * Insert a type in a closure
  2303      */
  2304     public List<Type> insert(List<Type> cl, Type t) {
  2305         if (cl.isEmpty() || t.tsym.precedes(cl.head.tsym, this)) {
  2306             return cl.prepend(t);
  2307         } else if (cl.head.tsym.precedes(t.tsym, this)) {
  2308             return insert(cl.tail, t).prepend(cl.head);
  2309         } else {
  2310             return cl;
  2314     /**
  2315      * Form the union of two closures
  2316      */
  2317     public List<Type> union(List<Type> cl1, List<Type> cl2) {
  2318         if (cl1.isEmpty()) {
  2319             return cl2;
  2320         } else if (cl2.isEmpty()) {
  2321             return cl1;
  2322         } else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) {
  2323             return union(cl1.tail, cl2).prepend(cl1.head);
  2324         } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) {
  2325             return union(cl1, cl2.tail).prepend(cl2.head);
  2326         } else {
  2327             return union(cl1.tail, cl2.tail).prepend(cl1.head);
  2331     /**
  2332      * Intersect two closures
  2333      */
  2334     public List<Type> intersect(List<Type> cl1, List<Type> cl2) {
  2335         if (cl1 == cl2)
  2336             return cl1;
  2337         if (cl1.isEmpty() || cl2.isEmpty())
  2338             return List.nil();
  2339         if (cl1.head.tsym.precedes(cl2.head.tsym, this))
  2340             return intersect(cl1.tail, cl2);
  2341         if (cl2.head.tsym.precedes(cl1.head.tsym, this))
  2342             return intersect(cl1, cl2.tail);
  2343         if (isSameType(cl1.head, cl2.head))
  2344             return intersect(cl1.tail, cl2.tail).prepend(cl1.head);
  2345         if (cl1.head.tsym == cl2.head.tsym &&
  2346             cl1.head.tag == CLASS && cl2.head.tag == CLASS) {
  2347             if (cl1.head.isParameterized() && cl2.head.isParameterized()) {
  2348                 Type merge = merge(cl1.head,cl2.head);
  2349                 return intersect(cl1.tail, cl2.tail).prepend(merge);
  2351             if (cl1.head.isRaw() || cl2.head.isRaw())
  2352                 return intersect(cl1.tail, cl2.tail).prepend(erasure(cl1.head));
  2354         return intersect(cl1.tail, cl2.tail);
  2356     // where
  2357         class TypePair {
  2358             final Type t1;
  2359             final Type t2;
  2360             TypePair(Type t1, Type t2) {
  2361                 this.t1 = t1;
  2362                 this.t2 = t2;
  2364             @Override
  2365             public int hashCode() {
  2366                 return 127 * Types.this.hashCode(t1) + Types.this.hashCode(t2);
  2368             @Override
  2369             public boolean equals(Object obj) {
  2370                 if (!(obj instanceof TypePair))
  2371                     return false;
  2372                 TypePair typePair = (TypePair)obj;
  2373                 return isSameType(t1, typePair.t1)
  2374                     && isSameType(t2, typePair.t2);
  2377         Set<TypePair> mergeCache = new HashSet<TypePair>();
  2378         private Type merge(Type c1, Type c2) {
  2379             ClassType class1 = (ClassType) c1;
  2380             List<Type> act1 = class1.getTypeArguments();
  2381             ClassType class2 = (ClassType) c2;
  2382             List<Type> act2 = class2.getTypeArguments();
  2383             ListBuffer<Type> merged = new ListBuffer<Type>();
  2384             List<Type> typarams = class1.tsym.type.getTypeArguments();
  2386             while (act1.nonEmpty() && act2.nonEmpty() && typarams.nonEmpty()) {
  2387                 if (containsType(act1.head, act2.head)) {
  2388                     merged.append(act1.head);
  2389                 } else if (containsType(act2.head, act1.head)) {
  2390                     merged.append(act2.head);
  2391                 } else {
  2392                     TypePair pair = new TypePair(c1, c2);
  2393                     Type m;
  2394                     if (mergeCache.add(pair)) {
  2395                         m = new WildcardType(lub(upperBound(act1.head),
  2396                                                  upperBound(act2.head)),
  2397                                              BoundKind.EXTENDS,
  2398                                              syms.boundClass);
  2399                         mergeCache.remove(pair);
  2400                     } else {
  2401                         m = new WildcardType(syms.objectType,
  2402                                              BoundKind.UNBOUND,
  2403                                              syms.boundClass);
  2405                     merged.append(m.withTypeVar(typarams.head));
  2407                 act1 = act1.tail;
  2408                 act2 = act2.tail;
  2409                 typarams = typarams.tail;
  2411             assert(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
  2412             return new ClassType(class1.getEnclosingType(), merged.toList(), class1.tsym);
  2415     /**
  2416      * Return the minimum type of a closure, a compound type if no
  2417      * unique minimum exists.
  2418      */
  2419     private Type compoundMin(List<Type> cl) {
  2420         if (cl.isEmpty()) return syms.objectType;
  2421         List<Type> compound = closureMin(cl);
  2422         if (compound.isEmpty())
  2423             return null;
  2424         else if (compound.tail.isEmpty())
  2425             return compound.head;
  2426         else
  2427             return makeCompoundType(compound);
  2430     /**
  2431      * Return the minimum types of a closure, suitable for computing
  2432      * compoundMin or glb.
  2433      */
  2434     private List<Type> closureMin(List<Type> cl) {
  2435         ListBuffer<Type> classes = lb();
  2436         ListBuffer<Type> interfaces = lb();
  2437         while (!cl.isEmpty()) {
  2438             Type current = cl.head;
  2439             if (current.isInterface())
  2440                 interfaces.append(current);
  2441             else
  2442                 classes.append(current);
  2443             ListBuffer<Type> candidates = lb();
  2444             for (Type t : cl.tail) {
  2445                 if (!isSubtypeNoCapture(current, t))
  2446                     candidates.append(t);
  2448             cl = candidates.toList();
  2450         return classes.appendList(interfaces).toList();
  2453     /**
  2454      * Return the least upper bound of pair of types.  if the lub does
  2455      * not exist return null.
  2456      */
  2457     public Type lub(Type t1, Type t2) {
  2458         return lub(List.of(t1, t2));
  2461     /**
  2462      * Return the least upper bound (lub) of set of types.  If the lub
  2463      * does not exist return the type of null (bottom).
  2464      */
  2465     public Type lub(List<Type> ts) {
  2466         final int ARRAY_BOUND = 1;
  2467         final int CLASS_BOUND = 2;
  2468         int boundkind = 0;
  2469         for (Type t : ts) {
  2470             switch (t.tag) {
  2471             case CLASS:
  2472                 boundkind |= CLASS_BOUND;
  2473                 break;
  2474             case ARRAY:
  2475                 boundkind |= ARRAY_BOUND;
  2476                 break;
  2477             case  TYPEVAR:
  2478                 do {
  2479                     t = t.getUpperBound();
  2480                 } while (t.tag == TYPEVAR);
  2481                 if (t.tag == ARRAY) {
  2482                     boundkind |= ARRAY_BOUND;
  2483                 } else {
  2484                     boundkind |= CLASS_BOUND;
  2486                 break;
  2487             default:
  2488                 if (t.isPrimitive())
  2489                     return syms.errType;
  2492         switch (boundkind) {
  2493         case 0:
  2494             return syms.botType;
  2496         case ARRAY_BOUND:
  2497             // calculate lub(A[], B[])
  2498             List<Type> elements = Type.map(ts, elemTypeFun);
  2499             for (Type t : elements) {
  2500                 if (t.isPrimitive()) {
  2501                     // if a primitive type is found, then return
  2502                     // arraySuperType unless all the types are the
  2503                     // same
  2504                     Type first = ts.head;
  2505                     for (Type s : ts.tail) {
  2506                         if (!isSameType(first, s)) {
  2507                              // lub(int[], B[]) is Cloneable & Serializable
  2508                             return arraySuperType();
  2511                     // all the array types are the same, return one
  2512                     // lub(int[], int[]) is int[]
  2513                     return first;
  2516             // lub(A[], B[]) is lub(A, B)[]
  2517             return new ArrayType(lub(elements), syms.arrayClass);
  2519         case CLASS_BOUND:
  2520             // calculate lub(A, B)
  2521             while (ts.head.tag != CLASS && ts.head.tag != TYPEVAR)
  2522                 ts = ts.tail;
  2523             assert !ts.isEmpty();
  2524             List<Type> cl = closure(ts.head);
  2525             for (Type t : ts.tail) {
  2526                 if (t.tag == CLASS || t.tag == TYPEVAR)
  2527                     cl = intersect(cl, closure(t));
  2529             return compoundMin(cl);
  2531         default:
  2532             // calculate lub(A, B[])
  2533             List<Type> classes = List.of(arraySuperType());
  2534             for (Type t : ts) {
  2535                 if (t.tag != ARRAY) // Filter out any arrays
  2536                     classes = classes.prepend(t);
  2538             // lub(A, B[]) is lub(A, arraySuperType)
  2539             return lub(classes);
  2542     // where
  2543         private Type arraySuperType = null;
  2544         private Type arraySuperType() {
  2545             // initialized lazily to avoid problems during compiler startup
  2546             if (arraySuperType == null) {
  2547                 synchronized (this) {
  2548                     if (arraySuperType == null) {
  2549                         // JLS 10.8: all arrays implement Cloneable and Serializable.
  2550                         arraySuperType = makeCompoundType(List.of(syms.serializableType,
  2551                                                                   syms.cloneableType),
  2552                                                           syms.objectType);
  2556             return arraySuperType;
  2558     // </editor-fold>
  2560     // <editor-fold defaultstate="collapsed" desc="Greatest lower bound">
  2561     public Type glb(Type t, Type s) {
  2562         if (s == null)
  2563             return t;
  2564         else if (isSubtypeNoCapture(t, s))
  2565             return t;
  2566         else if (isSubtypeNoCapture(s, t))
  2567             return s;
  2569         List<Type> closure = union(closure(t), closure(s));
  2570         List<Type> bounds = closureMin(closure);
  2572         if (bounds.isEmpty()) {             // length == 0
  2573             return syms.objectType;
  2574         } else if (bounds.tail.isEmpty()) { // length == 1
  2575             return bounds.head;
  2576         } else {                            // length > 1
  2577             int classCount = 0;
  2578             for (Type bound : bounds)
  2579                 if (!bound.isInterface())
  2580                     classCount++;
  2581             if (classCount > 1)
  2582                 return syms.errType;
  2584         return makeCompoundType(bounds);
  2586     // </editor-fold>
  2588     // <editor-fold defaultstate="collapsed" desc="hashCode">
  2589     /**
  2590      * Compute a hash code on a type.
  2591      */
  2592     public static int hashCode(Type t) {
  2593         return hashCode.visit(t);
  2595     // where
  2596         private static final UnaryVisitor<Integer> hashCode = new UnaryVisitor<Integer>() {
  2598             public Integer visitType(Type t, Void ignored) {
  2599                 return t.tag;
  2602             @Override
  2603             public Integer visitClassType(ClassType t, Void ignored) {
  2604                 int result = visit(t.getEnclosingType());
  2605                 result *= 127;
  2606                 result += t.tsym.flatName().hashCode();
  2607                 for (Type s : t.getTypeArguments()) {
  2608                     result *= 127;
  2609                     result += visit(s);
  2611                 return result;
  2614             @Override
  2615             public Integer visitWildcardType(WildcardType t, Void ignored) {
  2616                 int result = t.kind.hashCode();
  2617                 if (t.type != null) {
  2618                     result *= 127;
  2619                     result += visit(t.type);
  2621                 return result;
  2624             @Override
  2625             public Integer visitArrayType(ArrayType t, Void ignored) {
  2626                 return visit(t.elemtype) + 12;
  2629             @Override
  2630             public Integer visitTypeVar(TypeVar t, Void ignored) {
  2631                 return System.identityHashCode(t.tsym);
  2634             @Override
  2635             public Integer visitUndetVar(UndetVar t, Void ignored) {
  2636                 return System.identityHashCode(t);
  2639             @Override
  2640             public Integer visitErrorType(ErrorType t, Void ignored) {
  2641                 return 0;
  2643         };
  2644     // </editor-fold>
  2646     // <editor-fold defaultstate="collapsed" desc="Return-Type-Substitutable">
  2647     /**
  2648      * Does t have a result that is a subtype of the result type of s,
  2649      * suitable for covariant returns?  It is assumed that both types
  2650      * are (possibly polymorphic) method types.  Monomorphic method
  2651      * types are handled in the obvious way.  Polymorphic method types
  2652      * require renaming all type variables of one to corresponding
  2653      * type variables in the other, where correspondence is by
  2654      * position in the type parameter list. */
  2655     public boolean resultSubtype(Type t, Type s, Warner warner) {
  2656         List<Type> tvars = t.getTypeArguments();
  2657         List<Type> svars = s.getTypeArguments();
  2658         Type tres = t.getReturnType();
  2659         Type sres = subst(s.getReturnType(), svars, tvars);
  2660         return covariantReturnType(tres, sres, warner);
  2663     /**
  2664      * Return-Type-Substitutable.
  2665      * @see <a href="http://java.sun.com/docs/books/jls/">The Java
  2666      * Language Specification, Third Ed. (8.4.5)</a>
  2667      */
  2668     public boolean returnTypeSubstitutable(Type r1, Type r2) {
  2669         if (hasSameArgs(r1, r2))
  2670             return resultSubtype(r1, r2, Warner.noWarnings);
  2671         else
  2672             return covariantReturnType(r1.getReturnType(),
  2673                                        erasure(r2.getReturnType()),
  2674                                        Warner.noWarnings);
  2677     public boolean returnTypeSubstitutable(Type r1,
  2678                                            Type r2, Type r2res,
  2679                                            Warner warner) {
  2680         if (isSameType(r1.getReturnType(), r2res))
  2681             return true;
  2682         if (r1.getReturnType().isPrimitive() || r2res.isPrimitive())
  2683             return false;
  2685         if (hasSameArgs(r1, r2))
  2686             return covariantReturnType(r1.getReturnType(), r2res, warner);
  2687         if (!source.allowCovariantReturns())
  2688             return false;
  2689         if (isSubtypeUnchecked(r1.getReturnType(), r2res, warner))
  2690             return true;
  2691         if (!isSubtype(r1.getReturnType(), erasure(r2res)))
  2692             return false;
  2693         warner.warnUnchecked();
  2694         return true;
  2697     /**
  2698      * Is t an appropriate return type in an overrider for a
  2699      * method that returns s?
  2700      */
  2701     public boolean covariantReturnType(Type t, Type s, Warner warner) {
  2702         return
  2703             isSameType(t, s) ||
  2704             source.allowCovariantReturns() &&
  2705             !t.isPrimitive() &&
  2706             !s.isPrimitive() &&
  2707             isAssignable(t, s, warner);
  2709     // </editor-fold>
  2711     // <editor-fold defaultstate="collapsed" desc="Box/unbox support">
  2712     /**
  2713      * Return the class that boxes the given primitive.
  2714      */
  2715     public ClassSymbol boxedClass(Type t) {
  2716         return reader.enterClass(syms.boxedName[t.tag]);
  2719     /**
  2720      * Return the primitive type corresponding to a boxed type.
  2721      */
  2722     public Type unboxedType(Type t) {
  2723         if (allowBoxing) {
  2724             for (int i=0; i<syms.boxedName.length; i++) {
  2725                 Name box = syms.boxedName[i];
  2726                 if (box != null &&
  2727                     asSuper(t, reader.enterClass(box)) != null)
  2728                     return syms.typeOfTag[i];
  2731         return Type.noType;
  2733     // </editor-fold>
  2735     // <editor-fold defaultstate="collapsed" desc="Capture conversion">
  2736     /*
  2737      * JLS 3rd Ed. 5.1.10 Capture Conversion:
  2739      * Let G name a generic type declaration with n formal type
  2740      * parameters A1 ... An with corresponding bounds U1 ... Un. There
  2741      * exists a capture conversion from G<T1 ... Tn> to G<S1 ... Sn>,
  2742      * where, for 1 <= i <= n:
  2744      * + If Ti is a wildcard type argument (4.5.1) of the form ? then
  2745      *   Si is a fresh type variable whose upper bound is
  2746      *   Ui[A1 := S1, ..., An := Sn] and whose lower bound is the null
  2747      *   type.
  2749      * + If Ti is a wildcard type argument of the form ? extends Bi,
  2750      *   then Si is a fresh type variable whose upper bound is
  2751      *   glb(Bi, Ui[A1 := S1, ..., An := Sn]) and whose lower bound is
  2752      *   the null type, where glb(V1,... ,Vm) is V1 & ... & Vm. It is
  2753      *   a compile-time error if for any two classes (not interfaces)
  2754      *   Vi and Vj,Vi is not a subclass of Vj or vice versa.
  2756      * + If Ti is a wildcard type argument of the form ? super Bi,
  2757      *   then Si is a fresh type variable whose upper bound is
  2758      *   Ui[A1 := S1, ..., An := Sn] and whose lower bound is Bi.
  2760      * + Otherwise, Si = Ti.
  2762      * Capture conversion on any type other than a parameterized type
  2763      * (4.5) acts as an identity conversion (5.1.1). Capture
  2764      * conversions never require a special action at run time and
  2765      * therefore never throw an exception at run time.
  2767      * Capture conversion is not applied recursively.
  2768      */
  2769     /**
  2770      * Capture conversion as specified by JLS 3rd Ed.
  2771      */
  2772     public Type capture(Type t) {
  2773         if (t.tag != CLASS)
  2774             return t;
  2775         ClassType cls = (ClassType)t;
  2776         if (cls.isRaw() || !cls.isParameterized())
  2777             return cls;
  2779         ClassType G = (ClassType)cls.asElement().asType();
  2780         List<Type> A = G.getTypeArguments();
  2781         List<Type> T = cls.getTypeArguments();
  2782         List<Type> S = freshTypeVariables(T);
  2784         List<Type> currentA = A;
  2785         List<Type> currentT = T;
  2786         List<Type> currentS = S;
  2787         boolean captured = false;
  2788         while (!currentA.isEmpty() &&
  2789                !currentT.isEmpty() &&
  2790                !currentS.isEmpty()) {
  2791             if (currentS.head != currentT.head) {
  2792                 captured = true;
  2793                 WildcardType Ti = (WildcardType)currentT.head;
  2794                 Type Ui = currentA.head.getUpperBound();
  2795                 CapturedType Si = (CapturedType)currentS.head;
  2796                 if (Ui == null)
  2797                     Ui = syms.objectType;
  2798                 switch (Ti.kind) {
  2799                 case UNBOUND:
  2800                     Si.bound = subst(Ui, A, S);
  2801                     Si.lower = syms.botType;
  2802                     break;
  2803                 case EXTENDS:
  2804                     Si.bound = glb(Ti.getExtendsBound(), subst(Ui, A, S));
  2805                     Si.lower = syms.botType;
  2806                     break;
  2807                 case SUPER:
  2808                     Si.bound = subst(Ui, A, S);
  2809                     Si.lower = Ti.getSuperBound();
  2810                     break;
  2812                 if (Si.bound == Si.lower)
  2813                     currentS.head = Si.bound;
  2815             currentA = currentA.tail;
  2816             currentT = currentT.tail;
  2817             currentS = currentS.tail;
  2819         if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty())
  2820             return erasure(t); // some "rare" type involved
  2822         if (captured)
  2823             return new ClassType(cls.getEnclosingType(), S, cls.tsym);
  2824         else
  2825             return t;
  2827     // where
  2828         private List<Type> freshTypeVariables(List<Type> types) {
  2829             ListBuffer<Type> result = lb();
  2830             for (Type t : types) {
  2831                 if (t.tag == WILDCARD) {
  2832                     Type bound = ((WildcardType)t).getExtendsBound();
  2833                     if (bound == null)
  2834                         bound = syms.objectType;
  2835                     result.append(new CapturedType(capturedName,
  2836                                                    syms.noSymbol,
  2837                                                    bound,
  2838                                                    syms.botType,
  2839                                                    (WildcardType)t));
  2840                 } else {
  2841                     result.append(t);
  2844             return result.toList();
  2846     // </editor-fold>
  2848     // <editor-fold defaultstate="collapsed" desc="Internal utility methods">
  2849     private List<Type> upperBounds(List<Type> ss) {
  2850         if (ss.isEmpty()) return ss;
  2851         Type head = upperBound(ss.head);
  2852         List<Type> tail = upperBounds(ss.tail);
  2853         if (head != ss.head || tail != ss.tail)
  2854             return tail.prepend(head);
  2855         else
  2856             return ss;
  2859     private boolean sideCast(Type from, Type to, Warner warn) {
  2860         // We are casting from type $from$ to type $to$, which are
  2861         // non-final unrelated types.  This method
  2862         // tries to reject a cast by transferring type parameters
  2863         // from $to$ to $from$ by common superinterfaces.
  2864         boolean reverse = false;
  2865         Type target = to;
  2866         if ((to.tsym.flags() & INTERFACE) == 0) {
  2867             assert (from.tsym.flags() & INTERFACE) != 0;
  2868             reverse = true;
  2869             to = from;
  2870             from = target;
  2872         List<Type> commonSupers = superClosure(to, erasure(from));
  2873         boolean giveWarning = commonSupers.isEmpty();
  2874         // The arguments to the supers could be unified here to
  2875         // get a more accurate analysis
  2876         while (commonSupers.nonEmpty()) {
  2877             Type t1 = asSuper(from, commonSupers.head.tsym);
  2878             Type t2 = commonSupers.head; // same as asSuper(to, commonSupers.head.tsym);
  2879             if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
  2880                 return false;
  2881             giveWarning = giveWarning || (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2));
  2882             commonSupers = commonSupers.tail;
  2884         if (giveWarning && !isReifiable(to))
  2885             warn.warnUnchecked();
  2886         if (!source.allowCovariantReturns())
  2887             // reject if there is a common method signature with
  2888             // incompatible return types.
  2889             chk.checkCompatibleAbstracts(warn.pos(), from, to);
  2890         return true;
  2893     private boolean sideCastFinal(Type from, Type to, Warner warn) {
  2894         // We are casting from type $from$ to type $to$, which are
  2895         // unrelated types one of which is final and the other of
  2896         // which is an interface.  This method
  2897         // tries to reject a cast by transferring type parameters
  2898         // from the final class to the interface.
  2899         boolean reverse = false;
  2900         Type target = to;
  2901         if ((to.tsym.flags() & INTERFACE) == 0) {
  2902             assert (from.tsym.flags() & INTERFACE) != 0;
  2903             reverse = true;
  2904             to = from;
  2905             from = target;
  2907         assert (from.tsym.flags() & FINAL) != 0;
  2908         Type t1 = asSuper(from, to.tsym);
  2909         if (t1 == null) return false;
  2910         Type t2 = to;
  2911         if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
  2912             return false;
  2913         if (!source.allowCovariantReturns())
  2914             // reject if there is a common method signature with
  2915             // incompatible return types.
  2916             chk.checkCompatibleAbstracts(warn.pos(), from, to);
  2917         if (!isReifiable(target) &&
  2918             (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2)))
  2919             warn.warnUnchecked();
  2920         return true;
  2923     private boolean giveWarning(Type from, Type to) {
  2924         // To and from are (possibly different) parameterizations
  2925         // of the same class or interface
  2926         return to.isParameterized() && !containsType(to.getTypeArguments(), from.getTypeArguments());
  2929     private List<Type> superClosure(Type t, Type s) {
  2930         List<Type> cl = List.nil();
  2931         for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
  2932             if (isSubtype(s, erasure(l.head))) {
  2933                 cl = insert(cl, l.head);
  2934             } else {
  2935                 cl = union(cl, superClosure(l.head, s));
  2938         return cl;
  2941     private boolean containsTypeEquivalent(Type t, Type s) {
  2942         return
  2943             isSameType(t, s) || // shortcut
  2944             containsType(t, s) && containsType(s, t);
  2947     /**
  2948      * Adapt a type by computing a substitution which maps a source
  2949      * type to a target type.
  2951      * @param source    the source type
  2952      * @param target    the target type
  2953      * @param from      the type variables of the computed substitution
  2954      * @param to        the types of the computed substitution.
  2955      */
  2956     public void adapt(Type source,
  2957                        Type target,
  2958                        ListBuffer<Type> from,
  2959                        ListBuffer<Type> to) throws AdaptFailure {
  2960         Map<Symbol,Type> mapping = new HashMap<Symbol,Type>();
  2961         adaptRecursive(source, target, from, to, mapping);
  2962         List<Type> fromList = from.toList();
  2963         List<Type> toList = to.toList();
  2964         while (!fromList.isEmpty()) {
  2965             Type val = mapping.get(fromList.head.tsym);
  2966             if (toList.head != val)
  2967                 toList.head = val;
  2968             fromList = fromList.tail;
  2969             toList = toList.tail;
  2972     // where
  2973         private void adaptRecursive(Type source,
  2974                                     Type target,
  2975                                     ListBuffer<Type> from,
  2976                                     ListBuffer<Type> to,
  2977                                     Map<Symbol,Type> mapping) throws AdaptFailure {
  2978             if (source.tag == TYPEVAR) {
  2979                 // Check to see if there is
  2980                 // already a mapping for $source$, in which case
  2981                 // the old mapping will be merged with the new
  2982                 Type val = mapping.get(source.tsym);
  2983                 if (val != null) {
  2984                     if (val.isSuperBound() && target.isSuperBound()) {
  2985                         val = isSubtype(lowerBound(val), lowerBound(target))
  2986                             ? target : val;
  2987                     } else if (val.isExtendsBound() && target.isExtendsBound()) {
  2988                         val = isSubtype(upperBound(val), upperBound(target))
  2989                             ? val : target;
  2990                     } else if (!isSameType(val, target)) {
  2991                         throw new AdaptFailure();
  2993                 } else {
  2994                     val = target;
  2995                     from.append(source);
  2996                     to.append(target);
  2998                 mapping.put(source.tsym, val);
  2999             } else if (source.tag == target.tag) {
  3000                 switch (source.tag) {
  3001                     case CLASS:
  3002                         adapt(source.allparams(), target.allparams(),
  3003                               from, to, mapping);
  3004                         break;
  3005                     case ARRAY:
  3006                         adaptRecursive(elemtype(source), elemtype(target),
  3007                                        from, to, mapping);
  3008                         break;
  3009                     case WILDCARD:
  3010                         if (source.isExtendsBound()) {
  3011                             adaptRecursive(upperBound(source), upperBound(target),
  3012                                            from, to, mapping);
  3013                         } else if (source.isSuperBound()) {
  3014                             adaptRecursive(lowerBound(source), lowerBound(target),
  3015                                            from, to, mapping);
  3017                         break;
  3021         public static class AdaptFailure extends Exception {
  3022             static final long serialVersionUID = -7490231548272701566L;
  3025     /**
  3026      * Adapt a type by computing a substitution which maps a list of
  3027      * source types to a list of target types.
  3029      * @param source    the source type
  3030      * @param target    the target type
  3031      * @param from      the type variables of the computed substitution
  3032      * @param to        the types of the computed substitution.
  3033      */
  3034     private void adapt(List<Type> source,
  3035                        List<Type> target,
  3036                        ListBuffer<Type> from,
  3037                        ListBuffer<Type> to,
  3038                        Map<Symbol,Type> mapping) throws AdaptFailure {
  3039         if (source.length() == target.length()) {
  3040             while (source.nonEmpty()) {
  3041                 adaptRecursive(source.head, target.head, from, to, mapping);
  3042                 source = source.tail;
  3043                 target = target.tail;
  3048     private void adaptSelf(Type t,
  3049                            ListBuffer<Type> from,
  3050                            ListBuffer<Type> to) {
  3051         try {
  3052             //if (t.tsym.type != t)
  3053                 adapt(t.tsym.type, t, from, to);
  3054         } catch (AdaptFailure ex) {
  3055             // Adapt should never fail calculating a mapping from
  3056             // t.tsym.type to t as there can be no merge problem.
  3057             throw new AssertionError(ex);
  3061     /**
  3062      * Rewrite all type variables (universal quantifiers) in the given
  3063      * type to wildcards (existential quantifiers).  This is used to
  3064      * determine if a cast is allowed.  For example, if high is true
  3065      * and {@code T <: Number}, then {@code List<T>} is rewritten to
  3066      * {@code List<?  extends Number>}.  Since {@code List<Integer> <:
  3067      * List<? extends Number>} a {@code List<T>} can be cast to {@code
  3068      * List<Integer>} with a warning.
  3069      * @param t a type
  3070      * @param high if true return an upper bound; otherwise a lower
  3071      * bound
  3072      * @param rewriteTypeVars only rewrite captured wildcards if false;
  3073      * otherwise rewrite all type variables
  3074      * @return the type rewritten with wildcards (existential
  3075      * quantifiers) only
  3076      */
  3077     private Type rewriteQuantifiers(Type t, boolean high, boolean rewriteTypeVars) {
  3078         ListBuffer<Type> from = new ListBuffer<Type>();
  3079         ListBuffer<Type> to = new ListBuffer<Type>();
  3080         adaptSelf(t, from, to);
  3081         ListBuffer<Type> rewritten = new ListBuffer<Type>();
  3082         List<Type> formals = from.toList();
  3083         boolean changed = false;
  3084         for (Type arg : to.toList()) {
  3085             Type bound;
  3086             if (rewriteTypeVars && arg.tag == TYPEVAR) {
  3087                 TypeVar tv = (TypeVar)arg;
  3088                 bound = high ? tv.bound : syms.botType;
  3089             } else {
  3090                 bound = high ? upperBound(arg) : lowerBound(arg);
  3092             Type newarg = bound;
  3093             if (arg != bound) {
  3094                 changed = true;
  3095                 newarg = high ? makeExtendsWildcard(bound, (TypeVar)formals.head)
  3096                               : makeSuperWildcard(bound, (TypeVar)formals.head);
  3098             rewritten.append(newarg);
  3099             formals = formals.tail;
  3101         if (changed)
  3102             return subst(t.tsym.type, from.toList(), rewritten.toList());
  3103         else
  3104             return t;
  3107     /**
  3108      * Create a wildcard with the given upper (extends) bound; create
  3109      * an unbounded wildcard if bound is Object.
  3111      * @param bound the upper bound
  3112      * @param formal the formal type parameter that will be
  3113      * substituted by the wildcard
  3114      */
  3115     private WildcardType makeExtendsWildcard(Type bound, TypeVar formal) {
  3116         if (bound == syms.objectType) {
  3117             return new WildcardType(syms.objectType,
  3118                                     BoundKind.UNBOUND,
  3119                                     syms.boundClass,
  3120                                     formal);
  3121         } else {
  3122             return new WildcardType(bound,
  3123                                     BoundKind.EXTENDS,
  3124                                     syms.boundClass,
  3125                                     formal);
  3129     /**
  3130      * Create a wildcard with the given lower (super) bound; create an
  3131      * unbounded wildcard if bound is bottom (type of {@code null}).
  3133      * @param bound the lower bound
  3134      * @param formal the formal type parameter that will be
  3135      * substituted by the wildcard
  3136      */
  3137     private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
  3138         if (bound.tag == BOT) {
  3139             return new WildcardType(syms.objectType,
  3140                                     BoundKind.UNBOUND,
  3141                                     syms.boundClass,
  3142                                     formal);
  3143         } else {
  3144             return new WildcardType(bound,
  3145                                     BoundKind.SUPER,
  3146                                     syms.boundClass,
  3147                                     formal);
  3151     /**
  3152      * A wrapper for a type that allows use in sets.
  3153      */
  3154     class SingletonType {
  3155         final Type t;
  3156         SingletonType(Type t) {
  3157             this.t = t;
  3159         public int hashCode() {
  3160             return Types.this.hashCode(t);
  3162         public boolean equals(Object obj) {
  3163             return (obj instanceof SingletonType) &&
  3164                 isSameType(t, ((SingletonType)obj).t);
  3166         public String toString() {
  3167             return t.toString();
  3170     // </editor-fold>
  3172     // <editor-fold defaultstate="collapsed" desc="Visitors">
  3173     /**
  3174      * A default visitor for types.  All visitor methods except
  3175      * visitType are implemented by delegating to visitType.  Concrete
  3176      * subclasses must provide an implementation of visitType and can
  3177      * override other methods as needed.
  3179      * @param <R> the return type of the operation implemented by this
  3180      * visitor; use Void if no return type is needed.
  3181      * @param <S> the type of the second argument (the first being the
  3182      * type itself) of the operation implemented by this visitor; use
  3183      * Void if a second argument is not needed.
  3184      */
  3185     public static abstract class DefaultTypeVisitor<R,S> implements Type.Visitor<R,S> {
  3186         final public R visit(Type t, S s)               { return t.accept(this, s); }
  3187         public R visitClassType(ClassType t, S s)       { return visitType(t, s); }
  3188         public R visitWildcardType(WildcardType t, S s) { return visitType(t, s); }
  3189         public R visitArrayType(ArrayType t, S s)       { return visitType(t, s); }
  3190         public R visitMethodType(MethodType t, S s)     { return visitType(t, s); }
  3191         public R visitPackageType(PackageType t, S s)   { return visitType(t, s); }
  3192         public R visitTypeVar(TypeVar t, S s)           { return visitType(t, s); }
  3193         public R visitCapturedType(CapturedType t, S s) { return visitType(t, s); }
  3194         public R visitForAll(ForAll t, S s)             { return visitType(t, s); }
  3195         public R visitUndetVar(UndetVar t, S s)         { return visitType(t, s); }
  3196         public R visitErrorType(ErrorType t, S s)       { return visitType(t, s); }
  3199     /**
  3200      * A <em>simple</em> visitor for types.  This visitor is simple as
  3201      * captured wildcards, for-all types (generic methods), and
  3202      * undetermined type variables (part of inference) are hidden.
  3203      * Captured wildcards are hidden by treating them as type
  3204      * variables and the rest are hidden by visiting their qtypes.
  3206      * @param <R> the return type of the operation implemented by this
  3207      * visitor; use Void if no return type is needed.
  3208      * @param <S> the type of the second argument (the first being the
  3209      * type itself) of the operation implemented by this visitor; use
  3210      * Void if a second argument is not needed.
  3211      */
  3212     public static abstract class SimpleVisitor<R,S> extends DefaultTypeVisitor<R,S> {
  3213         @Override
  3214         public R visitCapturedType(CapturedType t, S s) {
  3215             return visitTypeVar(t, s);
  3217         @Override
  3218         public R visitForAll(ForAll t, S s) {
  3219             return visit(t.qtype, s);
  3221         @Override
  3222         public R visitUndetVar(UndetVar t, S s) {
  3223             return visit(t.qtype, s);
  3227     /**
  3228      * A plain relation on types.  That is a 2-ary function on the
  3229      * form Type&nbsp;&times;&nbsp;Type&nbsp;&rarr;&nbsp;Boolean.
  3230      * <!-- In plain text: Type x Type -> Boolean -->
  3231      */
  3232     public static abstract class TypeRelation extends SimpleVisitor<Boolean,Type> {}
  3234     /**
  3235      * A convenience visitor for implementing operations that only
  3236      * require one argument (the type itself), that is, unary
  3237      * operations.
  3239      * @param <R> the return type of the operation implemented by this
  3240      * visitor; use Void if no return type is needed.
  3241      */
  3242     public static abstract class UnaryVisitor<R> extends SimpleVisitor<R,Void> {
  3243         final public R visit(Type t) { return t.accept(this, null); }
  3246     /**
  3247      * A visitor for implementing a mapping from types to types.  The
  3248      * default behavior of this class is to implement the identity
  3249      * mapping (mapping a type to itself).  This can be overridden in
  3250      * subclasses.
  3252      * @param <S> the type of the second argument (the first being the
  3253      * type itself) of this mapping; use Void if a second argument is
  3254      * not needed.
  3255      */
  3256     public static class MapVisitor<S> extends DefaultTypeVisitor<Type,S> {
  3257         final public Type visit(Type t) { return t.accept(this, null); }
  3258         public Type visitType(Type t, S s) { return t; }
  3260     // </editor-fold>

mercurial