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

Sat, 01 Dec 2007 00:00:00 +0000

author
duke
date
Sat, 01 Dec 2007 00:00:00 +0000
changeset 1
9a66ca7c79fa
child 5
b45f8d4794b7
permissions
-rw-r--r--

Initial load

     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 == 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                 return asSuper(t.bound, sym);
  1326             @Override
  1327             public Type visitErrorType(ErrorType t, Symbol sym) {
  1328                 return t;
  1330         };
  1332     /**
  1333      * Return the base type of t or any of its outer types that starts
  1334      * with the given symbol.  If none exists, return null.
  1336      * @param t a type
  1337      * @param sym a symbol
  1338      */
  1339     public Type asOuterSuper(Type t, Symbol sym) {
  1340         switch (t.tag) {
  1341         case CLASS:
  1342             do {
  1343                 Type s = asSuper(t, sym);
  1344                 if (s != null) return s;
  1345                 t = t.getEnclosingType();
  1346             } while (t.tag == CLASS);
  1347             return null;
  1348         case ARRAY:
  1349             return isSubtype(t, sym.type) ? sym.type : null;
  1350         case TYPEVAR:
  1351             return asSuper(t, sym);
  1352         case ERROR:
  1353             return t;
  1354         default:
  1355             return null;
  1359     /**
  1360      * Return the base type of t or any of its enclosing types that
  1361      * starts with the given symbol.  If none exists, return null.
  1363      * @param t a type
  1364      * @param sym a symbol
  1365      */
  1366     public Type asEnclosingSuper(Type t, Symbol sym) {
  1367         switch (t.tag) {
  1368         case CLASS:
  1369             do {
  1370                 Type s = asSuper(t, sym);
  1371                 if (s != null) return s;
  1372                 Type outer = t.getEnclosingType();
  1373                 t = (outer.tag == CLASS) ? outer :
  1374                     (t.tsym.owner.enclClass() != null) ? t.tsym.owner.enclClass().type :
  1375                     Type.noType;
  1376             } while (t.tag == CLASS);
  1377             return null;
  1378         case ARRAY:
  1379             return isSubtype(t, sym.type) ? sym.type : null;
  1380         case TYPEVAR:
  1381             return asSuper(t, sym);
  1382         case ERROR:
  1383             return t;
  1384         default:
  1385             return null;
  1388     // </editor-fold>
  1390     // <editor-fold defaultstate="collapsed" desc="memberType">
  1391     /**
  1392      * The type of given symbol, seen as a member of t.
  1394      * @param t a type
  1395      * @param sym a symbol
  1396      */
  1397     public Type memberType(Type t, Symbol sym) {
  1398         return (sym.flags() & STATIC) != 0
  1399             ? sym.type
  1400             : memberType.visit(t, sym);
  1402     // where
  1403         private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
  1405             public Type visitType(Type t, Symbol sym) {
  1406                 return sym.type;
  1409             @Override
  1410             public Type visitWildcardType(WildcardType t, Symbol sym) {
  1411                 return memberType(upperBound(t), sym);
  1414             @Override
  1415             public Type visitClassType(ClassType t, Symbol sym) {
  1416                 Symbol owner = sym.owner;
  1417                 long flags = sym.flags();
  1418                 if (((flags & STATIC) == 0) && owner.type.isParameterized()) {
  1419                     Type base = asOuterSuper(t, owner);
  1420                     if (base != null) {
  1421                         List<Type> ownerParams = owner.type.allparams();
  1422                         List<Type> baseParams = base.allparams();
  1423                         if (ownerParams.nonEmpty()) {
  1424                             if (baseParams.isEmpty()) {
  1425                                 // then base is a raw type
  1426                                 return erasure(sym.type);
  1427                             } else {
  1428                                 return subst(sym.type, ownerParams, baseParams);
  1433                 return sym.type;
  1436             @Override
  1437             public Type visitTypeVar(TypeVar t, Symbol sym) {
  1438                 return memberType(t.bound, sym);
  1441             @Override
  1442             public Type visitErrorType(ErrorType t, Symbol sym) {
  1443                 return t;
  1445         };
  1446     // </editor-fold>
  1448     // <editor-fold defaultstate="collapsed" desc="isAssignable">
  1449     public boolean isAssignable(Type t, Type s) {
  1450         return isAssignable(t, s, Warner.noWarnings);
  1453     /**
  1454      * Is t assignable to s?<br>
  1455      * Equivalent to subtype except for constant values and raw
  1456      * types.<br>
  1457      * (not defined for Method and ForAll types)
  1458      */
  1459     public boolean isAssignable(Type t, Type s, Warner warn) {
  1460         if (t.tag == ERROR)
  1461             return true;
  1462         if (t.tag <= INT && t.constValue() != null) {
  1463             int value = ((Number)t.constValue()).intValue();
  1464             switch (s.tag) {
  1465             case BYTE:
  1466                 if (Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE)
  1467                     return true;
  1468                 break;
  1469             case CHAR:
  1470                 if (Character.MIN_VALUE <= value && value <= Character.MAX_VALUE)
  1471                     return true;
  1472                 break;
  1473             case SHORT:
  1474                 if (Short.MIN_VALUE <= value && value <= Short.MAX_VALUE)
  1475                     return true;
  1476                 break;
  1477             case INT:
  1478                 return true;
  1479             case CLASS:
  1480                 switch (unboxedType(s).tag) {
  1481                 case BYTE:
  1482                 case CHAR:
  1483                 case SHORT:
  1484                     return isAssignable(t, unboxedType(s), warn);
  1486                 break;
  1489         return isConvertible(t, s, warn);
  1491     // </editor-fold>
  1493     // <editor-fold defaultstate="collapsed" desc="erasure">
  1494     /**
  1495      * The erasure of t {@code |t|} -- the type that results when all
  1496      * type parameters in t are deleted.
  1497      */
  1498     public Type erasure(Type t) {
  1499         if (t.tag <= lastBaseTag)
  1500             return t; /* fast special case */
  1501         else
  1502             return erasure.visit(t);
  1504     // where
  1505         private UnaryVisitor<Type> erasure = new UnaryVisitor<Type>() {
  1506             public Type visitType(Type t, Void ignored) {
  1507                 if (t.tag <= lastBaseTag)
  1508                     return t; /*fast special case*/
  1509                 else
  1510                     return t.map(erasureFun);
  1513             @Override
  1514             public Type visitWildcardType(WildcardType t, Void ignored) {
  1515                 return erasure(upperBound(t));
  1518             @Override
  1519             public Type visitClassType(ClassType t, Void ignored) {
  1520                 return t.tsym.erasure(Types.this);
  1523             @Override
  1524             public Type visitTypeVar(TypeVar t, Void ignored) {
  1525                 return erasure(t.bound);
  1528             @Override
  1529             public Type visitErrorType(ErrorType t, Void ignored) {
  1530                 return t;
  1532         };
  1533     private Mapping erasureFun = new Mapping ("erasure") {
  1534             public Type apply(Type t) { return erasure(t); }
  1535         };
  1537     public List<Type> erasure(List<Type> ts) {
  1538         return Type.map(ts, erasureFun);
  1540     // </editor-fold>
  1542     // <editor-fold defaultstate="collapsed" desc="makeCompoundType">
  1543     /**
  1544      * Make a compound type from non-empty list of types
  1546      * @param bounds            the types from which the compound type is formed
  1547      * @param supertype         is objectType if all bounds are interfaces,
  1548      *                          null otherwise.
  1549      */
  1550     public Type makeCompoundType(List<Type> bounds,
  1551                                  Type supertype) {
  1552         ClassSymbol bc =
  1553             new ClassSymbol(ABSTRACT|PUBLIC|SYNTHETIC|COMPOUND|ACYCLIC,
  1554                             Type.moreInfo
  1555                                 ? names.fromString(bounds.toString())
  1556                                 : names.empty,
  1557                             syms.noSymbol);
  1558         if (bounds.head.tag == TYPEVAR)
  1559             // error condition, recover
  1560             bc.erasure_field = syms.objectType;
  1561         else
  1562             bc.erasure_field = erasure(bounds.head);
  1563         bc.members_field = new Scope(bc);
  1564         ClassType bt = (ClassType)bc.type;
  1565         bt.allparams_field = List.nil();
  1566         if (supertype != null) {
  1567             bt.supertype_field = supertype;
  1568             bt.interfaces_field = bounds;
  1569         } else {
  1570             bt.supertype_field = bounds.head;
  1571             bt.interfaces_field = bounds.tail;
  1573         assert bt.supertype_field.tsym.completer != null
  1574             || !bt.supertype_field.isInterface()
  1575             : bt.supertype_field;
  1576         return bt;
  1579     /**
  1580      * Same as {@link #makeCompoundType(List,Type)}, except that the
  1581      * second parameter is computed directly. Note that this might
  1582      * cause a symbol completion.  Hence, this version of
  1583      * makeCompoundType may not be called during a classfile read.
  1584      */
  1585     public Type makeCompoundType(List<Type> bounds) {
  1586         Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ?
  1587             supertype(bounds.head) : null;
  1588         return makeCompoundType(bounds, supertype);
  1591     /**
  1592      * A convenience wrapper for {@link #makeCompoundType(List)}; the
  1593      * arguments are converted to a list and passed to the other
  1594      * method.  Note that this might cause a symbol completion.
  1595      * Hence, this version of makeCompoundType may not be called
  1596      * during a classfile read.
  1597      */
  1598     public Type makeCompoundType(Type bound1, Type bound2) {
  1599         return makeCompoundType(List.of(bound1, bound2));
  1601     // </editor-fold>
  1603     // <editor-fold defaultstate="collapsed" desc="supertype">
  1604     public Type supertype(Type t) {
  1605         return supertype.visit(t);
  1607     // where
  1608         private UnaryVisitor<Type> supertype = new UnaryVisitor<Type>() {
  1610             public Type visitType(Type t, Void ignored) {
  1611                 // A note on wildcards: there is no good way to
  1612                 // determine a supertype for a super bounded wildcard.
  1613                 return null;
  1616             @Override
  1617             public Type visitClassType(ClassType t, Void ignored) {
  1618                 if (t.supertype_field == null) {
  1619                     Type supertype = ((ClassSymbol)t.tsym).getSuperclass();
  1620                     // An interface has no superclass; its supertype is Object.
  1621                     if (t.isInterface())
  1622                         supertype = ((ClassType)t.tsym.type).supertype_field;
  1623                     if (t.supertype_field == null) {
  1624                         List<Type> actuals = classBound(t).allparams();
  1625                         List<Type> formals = t.tsym.type.allparams();
  1626                         if (actuals.isEmpty()) {
  1627                             if (formals.isEmpty())
  1628                                 // Should not happen.  See comments below in interfaces
  1629                                 t.supertype_field = supertype;
  1630                             else
  1631                                 t.supertype_field = erasure(supertype);
  1632                         } else {
  1633                             t.supertype_field = subst(supertype, formals, actuals);
  1637                 return t.supertype_field;
  1640             /**
  1641              * The supertype is always a class type. If the type
  1642              * variable's bounds start with a class type, this is also
  1643              * the supertype.  Otherwise, the supertype is
  1644              * java.lang.Object.
  1645              */
  1646             @Override
  1647             public Type visitTypeVar(TypeVar t, Void ignored) {
  1648                 if (t.bound.tag == TYPEVAR ||
  1649                     (!t.bound.isCompound() && !t.bound.isInterface())) {
  1650                     return t.bound;
  1651                 } else {
  1652                     return supertype(t.bound);
  1656             @Override
  1657             public Type visitArrayType(ArrayType t, Void ignored) {
  1658                 if (t.elemtype.isPrimitive() || isSameType(t.elemtype, syms.objectType))
  1659                     return arraySuperType();
  1660                 else
  1661                     return new ArrayType(supertype(t.elemtype), t.tsym);
  1664             @Override
  1665             public Type visitErrorType(ErrorType t, Void ignored) {
  1666                 return t;
  1668         };
  1669     // </editor-fold>
  1671     // <editor-fold defaultstate="collapsed" desc="interfaces">
  1672     /**
  1673      * Return the interfaces implemented by this class.
  1674      */
  1675     public List<Type> interfaces(Type t) {
  1676         return interfaces.visit(t);
  1678     // where
  1679         private UnaryVisitor<List<Type>> interfaces = new UnaryVisitor<List<Type>>() {
  1681             public List<Type> visitType(Type t, Void ignored) {
  1682                 return List.nil();
  1685             @Override
  1686             public List<Type> visitClassType(ClassType t, Void ignored) {
  1687                 if (t.interfaces_field == null) {
  1688                     List<Type> interfaces = ((ClassSymbol)t.tsym).getInterfaces();
  1689                     if (t.interfaces_field == null) {
  1690                         // If t.interfaces_field is null, then t must
  1691                         // be a parameterized type (not to be confused
  1692                         // with a generic type declaration).
  1693                         // Terminology:
  1694                         //    Parameterized type: List<String>
  1695                         //    Generic type declaration: class List<E> { ... }
  1696                         // So t corresponds to List<String> and
  1697                         // t.tsym.type corresponds to List<E>.
  1698                         // The reason t must be parameterized type is
  1699                         // that completion will happen as a side
  1700                         // effect of calling
  1701                         // ClassSymbol.getInterfaces.  Since
  1702                         // t.interfaces_field is null after
  1703                         // completion, we can assume that t is not the
  1704                         // type of a class/interface declaration.
  1705                         assert t != t.tsym.type : t.toString();
  1706                         List<Type> actuals = t.allparams();
  1707                         List<Type> formals = t.tsym.type.allparams();
  1708                         if (actuals.isEmpty()) {
  1709                             if (formals.isEmpty()) {
  1710                                 // In this case t is not generic (nor raw).
  1711                                 // So this should not happen.
  1712                                 t.interfaces_field = interfaces;
  1713                             } else {
  1714                                 t.interfaces_field = erasure(interfaces);
  1716                         } else {
  1717                             t.interfaces_field =
  1718                                 upperBounds(subst(interfaces, formals, actuals));
  1722                 return t.interfaces_field;
  1725             @Override
  1726             public List<Type> visitTypeVar(TypeVar t, Void ignored) {
  1727                 if (t.bound.isCompound())
  1728                     return interfaces(t.bound);
  1730                 if (t.bound.isInterface())
  1731                     return List.of(t.bound);
  1733                 return List.nil();
  1735         };
  1736     // </editor-fold>
  1738     // <editor-fold defaultstate="collapsed" desc="isDerivedRaw">
  1739     Map<Type,Boolean> isDerivedRawCache = new HashMap<Type,Boolean>();
  1741     public boolean isDerivedRaw(Type t) {
  1742         Boolean result = isDerivedRawCache.get(t);
  1743         if (result == null) {
  1744             result = isDerivedRawInternal(t);
  1745             isDerivedRawCache.put(t, result);
  1747         return result;
  1750     public boolean isDerivedRawInternal(Type t) {
  1751         if (t.isErroneous())
  1752             return false;
  1753         return
  1754             t.isRaw() ||
  1755             supertype(t) != null && isDerivedRaw(supertype(t)) ||
  1756             isDerivedRaw(interfaces(t));
  1759     public boolean isDerivedRaw(List<Type> ts) {
  1760         List<Type> l = ts;
  1761         while (l.nonEmpty() && !isDerivedRaw(l.head)) l = l.tail;
  1762         return l.nonEmpty();
  1764     // </editor-fold>
  1766     // <editor-fold defaultstate="collapsed" desc="setBounds">
  1767     /**
  1768      * Set the bounds field of the given type variable to reflect a
  1769      * (possibly multiple) list of bounds.
  1770      * @param t                 a type variable
  1771      * @param bounds            the bounds, must be nonempty
  1772      * @param supertype         is objectType if all bounds are interfaces,
  1773      *                          null otherwise.
  1774      */
  1775     public void setBounds(TypeVar t, List<Type> bounds, Type supertype) {
  1776         if (bounds.tail.isEmpty())
  1777             t.bound = bounds.head;
  1778         else
  1779             t.bound = makeCompoundType(bounds, supertype);
  1780         t.rank_field = -1;
  1783     /**
  1784      * Same as {@link #setBounds(Type.TypeVar,List,Type)}, except that
  1785      * third parameter is computed directly.  Note that this test
  1786      * might cause a symbol completion.  Hence, this version of
  1787      * setBounds may not be called during a classfile read.
  1788      */
  1789     public void setBounds(TypeVar t, List<Type> bounds) {
  1790         Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ?
  1791             supertype(bounds.head) : null;
  1792         setBounds(t, bounds, supertype);
  1793         t.rank_field = -1;
  1795     // </editor-fold>
  1797     // <editor-fold defaultstate="collapsed" desc="getBounds">
  1798     /**
  1799      * Return list of bounds of the given type variable.
  1800      */
  1801     public List<Type> getBounds(TypeVar t) {
  1802         if (t.bound.isErroneous() || !t.bound.isCompound())
  1803             return List.of(t.bound);
  1804         else if ((erasure(t).tsym.flags() & INTERFACE) == 0)
  1805             return interfaces(t).prepend(supertype(t));
  1806         else
  1807             // No superclass was given in bounds.
  1808             // In this case, supertype is Object, erasure is first interface.
  1809             return interfaces(t);
  1811     // </editor-fold>
  1813     // <editor-fold defaultstate="collapsed" desc="classBound">
  1814     /**
  1815      * If the given type is a (possibly selected) type variable,
  1816      * return the bounding class of this type, otherwise return the
  1817      * type itself.
  1818      */
  1819     public Type classBound(Type t) {
  1820         return classBound.visit(t);
  1822     // where
  1823         private UnaryVisitor<Type> classBound = new UnaryVisitor<Type>() {
  1825             public Type visitType(Type t, Void ignored) {
  1826                 return t;
  1829             @Override
  1830             public Type visitClassType(ClassType t, Void ignored) {
  1831                 Type outer1 = classBound(t.getEnclosingType());
  1832                 if (outer1 != t.getEnclosingType())
  1833                     return new ClassType(outer1, t.getTypeArguments(), t.tsym);
  1834                 else
  1835                     return t;
  1838             @Override
  1839             public Type visitTypeVar(TypeVar t, Void ignored) {
  1840                 return classBound(supertype(t));
  1843             @Override
  1844             public Type visitErrorType(ErrorType t, Void ignored) {
  1845                 return t;
  1847         };
  1848     // </editor-fold>
  1850     // <editor-fold defaultstate="collapsed" desc="sub signature / override equivalence">
  1851     /**
  1852      * Returns true iff the first signature is a <em>sub
  1853      * signature</em> of the other.  This is <b>not</b> an equivalence
  1854      * relation.
  1856      * @see "The Java Language Specification, Third Ed. (8.4.2)."
  1857      * @see #overrideEquivalent(Type t, Type s)
  1858      * @param t first signature (possibly raw).
  1859      * @param s second signature (could be subjected to erasure).
  1860      * @return true if t is a sub signature of s.
  1861      */
  1862     public boolean isSubSignature(Type t, Type s) {
  1863         return hasSameArgs(t, s) || hasSameArgs(t, erasure(s));
  1866     /**
  1867      * Returns true iff these signatures are related by <em>override
  1868      * equivalence</em>.  This is the natural extension of
  1869      * isSubSignature to an equivalence relation.
  1871      * @see "The Java Language Specification, Third Ed. (8.4.2)."
  1872      * @see #isSubSignature(Type t, Type s)
  1873      * @param t a signature (possible raw, could be subjected to
  1874      * erasure).
  1875      * @param s a signature (possible raw, could be subjected to
  1876      * erasure).
  1877      * @return true if either argument is a sub signature of the other.
  1878      */
  1879     public boolean overrideEquivalent(Type t, Type s) {
  1880         return hasSameArgs(t, s) ||
  1881             hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s);
  1884     /**
  1885      * Does t have the same arguments as s?  It is assumed that both
  1886      * types are (possibly polymorphic) method types.  Monomorphic
  1887      * method types "have the same arguments", if their argument lists
  1888      * are equal.  Polymorphic method types "have the same arguments",
  1889      * if they have the same arguments after renaming all type
  1890      * variables of one to corresponding type variables in the other,
  1891      * where correspondence is by position in the type parameter list.
  1892      */
  1893     public boolean hasSameArgs(Type t, Type s) {
  1894         return hasSameArgs.visit(t, s);
  1896     // where
  1897         private TypeRelation hasSameArgs = new TypeRelation() {
  1899             public Boolean visitType(Type t, Type s) {
  1900                 throw new AssertionError();
  1903             @Override
  1904             public Boolean visitMethodType(MethodType t, Type s) {
  1905                 return s.tag == METHOD
  1906                     && containsTypeEquivalent(t.argtypes, s.getParameterTypes());
  1909             @Override
  1910             public Boolean visitForAll(ForAll t, Type s) {
  1911                 if (s.tag != FORALL)
  1912                     return false;
  1914                 ForAll forAll = (ForAll)s;
  1915                 return hasSameBounds(t, forAll)
  1916                     && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
  1919             @Override
  1920             public Boolean visitErrorType(ErrorType t, Type s) {
  1921                 return false;
  1923         };
  1924     // </editor-fold>
  1926     // <editor-fold defaultstate="collapsed" desc="subst">
  1927     public List<Type> subst(List<Type> ts,
  1928                             List<Type> from,
  1929                             List<Type> to) {
  1930         return new Subst(from, to).subst(ts);
  1933     /**
  1934      * Substitute all occurrences of a type in `from' with the
  1935      * corresponding type in `to' in 't'. Match lists `from' and `to'
  1936      * from the right: If lists have different length, discard leading
  1937      * elements of the longer list.
  1938      */
  1939     public Type subst(Type t, List<Type> from, List<Type> to) {
  1940         return new Subst(from, to).subst(t);
  1943     private class Subst extends UnaryVisitor<Type> {
  1944         List<Type> from;
  1945         List<Type> to;
  1947         public Subst(List<Type> from, List<Type> to) {
  1948             int fromLength = from.length();
  1949             int toLength = to.length();
  1950             while (fromLength > toLength) {
  1951                 fromLength--;
  1952                 from = from.tail;
  1954             while (fromLength < toLength) {
  1955                 toLength--;
  1956                 to = to.tail;
  1958             this.from = from;
  1959             this.to = to;
  1962         Type subst(Type t) {
  1963             if (from.tail == null)
  1964                 return t;
  1965             else
  1966                 return visit(t);
  1969         List<Type> subst(List<Type> ts) {
  1970             if (from.tail == null)
  1971                 return ts;
  1972             boolean wild = false;
  1973             if (ts.nonEmpty() && from.nonEmpty()) {
  1974                 Type head1 = subst(ts.head);
  1975                 List<Type> tail1 = subst(ts.tail);
  1976                 if (head1 != ts.head || tail1 != ts.tail)
  1977                     return tail1.prepend(head1);
  1979             return ts;
  1982         public Type visitType(Type t, Void ignored) {
  1983             return t;
  1986         @Override
  1987         public Type visitMethodType(MethodType t, Void ignored) {
  1988             List<Type> argtypes = subst(t.argtypes);
  1989             Type restype = subst(t.restype);
  1990             List<Type> thrown = subst(t.thrown);
  1991             if (argtypes == t.argtypes &&
  1992                 restype == t.restype &&
  1993                 thrown == t.thrown)
  1994                 return t;
  1995             else
  1996                 return new MethodType(argtypes, restype, thrown, t.tsym);
  1999         @Override
  2000         public Type visitTypeVar(TypeVar t, Void ignored) {
  2001             for (List<Type> from = this.from, to = this.to;
  2002                  from.nonEmpty();
  2003                  from = from.tail, to = to.tail) {
  2004                 if (t == from.head) {
  2005                     return to.head.withTypeVar(t);
  2008             return t;
  2011         @Override
  2012         public Type visitClassType(ClassType t, Void ignored) {
  2013             if (!t.isCompound()) {
  2014                 List<Type> typarams = t.getTypeArguments();
  2015                 List<Type> typarams1 = subst(typarams);
  2016                 Type outer = t.getEnclosingType();
  2017                 Type outer1 = subst(outer);
  2018                 if (typarams1 == typarams && outer1 == outer)
  2019                     return t;
  2020                 else
  2021                     return new ClassType(outer1, typarams1, t.tsym);
  2022             } else {
  2023                 Type st = subst(supertype(t));
  2024                 List<Type> is = upperBounds(subst(interfaces(t)));
  2025                 if (st == supertype(t) && is == interfaces(t))
  2026                     return t;
  2027                 else
  2028                     return makeCompoundType(is.prepend(st));
  2032         @Override
  2033         public Type visitWildcardType(WildcardType t, Void ignored) {
  2034             Type bound = t.type;
  2035             if (t.kind != BoundKind.UNBOUND)
  2036                 bound = subst(bound);
  2037             if (bound == t.type) {
  2038                 return t;
  2039             } else {
  2040                 if (t.isExtendsBound() && bound.isExtendsBound())
  2041                     bound = upperBound(bound);
  2042                 return new WildcardType(bound, t.kind, syms.boundClass, t.bound);
  2046         @Override
  2047         public Type visitArrayType(ArrayType t, Void ignored) {
  2048             Type elemtype = subst(t.elemtype);
  2049             if (elemtype == t.elemtype)
  2050                 return t;
  2051             else
  2052                 return new ArrayType(upperBound(elemtype), t.tsym);
  2055         @Override
  2056         public Type visitForAll(ForAll t, Void ignored) {
  2057             List<Type> tvars1 = substBounds(t.tvars, from, to);
  2058             Type qtype1 = subst(t.qtype);
  2059             if (tvars1 == t.tvars && qtype1 == t.qtype) {
  2060                 return t;
  2061             } else if (tvars1 == t.tvars) {
  2062                 return new ForAll(tvars1, qtype1);
  2063             } else {
  2064                 return new ForAll(tvars1, Types.this.subst(qtype1, t.tvars, tvars1));
  2068         @Override
  2069         public Type visitErrorType(ErrorType t, Void ignored) {
  2070             return t;
  2074     public List<Type> substBounds(List<Type> tvars,
  2075                                   List<Type> from,
  2076                                   List<Type> to) {
  2077         if (tvars.isEmpty())
  2078             return tvars;
  2079         if (tvars.tail.isEmpty())
  2080             // fast common case
  2081             return List.<Type>of(substBound((TypeVar)tvars.head, from, to));
  2082         ListBuffer<Type> newBoundsBuf = lb();
  2083         boolean changed = false;
  2084         // calculate new bounds
  2085         for (Type t : tvars) {
  2086             TypeVar tv = (TypeVar) t;
  2087             Type bound = subst(tv.bound, from, to);
  2088             if (bound != tv.bound)
  2089                 changed = true;
  2090             newBoundsBuf.append(bound);
  2092         if (!changed)
  2093             return tvars;
  2094         ListBuffer<Type> newTvars = lb();
  2095         // create new type variables without bounds
  2096         for (Type t : tvars) {
  2097             newTvars.append(new TypeVar(t.tsym, null, syms.botType));
  2099         // the new bounds should use the new type variables in place
  2100         // of the old
  2101         List<Type> newBounds = newBoundsBuf.toList();
  2102         from = tvars;
  2103         to = newTvars.toList();
  2104         for (; !newBounds.isEmpty(); newBounds = newBounds.tail) {
  2105             newBounds.head = subst(newBounds.head, from, to);
  2107         newBounds = newBoundsBuf.toList();
  2108         // set the bounds of new type variables to the new bounds
  2109         for (Type t : newTvars.toList()) {
  2110             TypeVar tv = (TypeVar) t;
  2111             tv.bound = newBounds.head;
  2112             newBounds = newBounds.tail;
  2114         return newTvars.toList();
  2117     public TypeVar substBound(TypeVar t, List<Type> from, List<Type> to) {
  2118         Type bound1 = subst(t.bound, from, to);
  2119         if (bound1 == t.bound)
  2120             return t;
  2121         else
  2122             return new TypeVar(t.tsym, bound1, syms.botType);
  2124     // </editor-fold>
  2126     // <editor-fold defaultstate="collapsed" desc="hasSameBounds">
  2127     /**
  2128      * Does t have the same bounds for quantified variables as s?
  2129      */
  2130     boolean hasSameBounds(ForAll t, ForAll s) {
  2131         List<Type> l1 = t.tvars;
  2132         List<Type> l2 = s.tvars;
  2133         while (l1.nonEmpty() && l2.nonEmpty() &&
  2134                isSameType(l1.head.getUpperBound(),
  2135                           subst(l2.head.getUpperBound(),
  2136                                 s.tvars,
  2137                                 t.tvars))) {
  2138             l1 = l1.tail;
  2139             l2 = l2.tail;
  2141         return l1.isEmpty() && l2.isEmpty();
  2143     // </editor-fold>
  2145     // <editor-fold defaultstate="collapsed" desc="newInstances">
  2146     /** Create new vector of type variables from list of variables
  2147      *  changing all recursive bounds from old to new list.
  2148      */
  2149     public List<Type> newInstances(List<Type> tvars) {
  2150         List<Type> tvars1 = Type.map(tvars, newInstanceFun);
  2151         for (List<Type> l = tvars1; l.nonEmpty(); l = l.tail) {
  2152             TypeVar tv = (TypeVar) l.head;
  2153             tv.bound = subst(tv.bound, tvars, tvars1);
  2155         return tvars1;
  2157     static private Mapping newInstanceFun = new Mapping("newInstanceFun") {
  2158             public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound()); }
  2159         };
  2160     // </editor-fold>
  2162     // <editor-fold defaultstate="collapsed" desc="rank">
  2163     /**
  2164      * The rank of a class is the length of the longest path between
  2165      * the class and java.lang.Object in the class inheritance
  2166      * graph. Undefined for all but reference types.
  2167      */
  2168     public int rank(Type t) {
  2169         switch(t.tag) {
  2170         case CLASS: {
  2171             ClassType cls = (ClassType)t;
  2172             if (cls.rank_field < 0) {
  2173                 Name fullname = cls.tsym.getQualifiedName();
  2174                 if (fullname == fullname.table.java_lang_Object)
  2175                     cls.rank_field = 0;
  2176                 else {
  2177                     int r = rank(supertype(cls));
  2178                     for (List<Type> l = interfaces(cls);
  2179                          l.nonEmpty();
  2180                          l = l.tail) {
  2181                         if (rank(l.head) > r)
  2182                             r = rank(l.head);
  2184                     cls.rank_field = r + 1;
  2187             return cls.rank_field;
  2189         case TYPEVAR: {
  2190             TypeVar tvar = (TypeVar)t;
  2191             if (tvar.rank_field < 0) {
  2192                 int r = rank(supertype(tvar));
  2193                 for (List<Type> l = interfaces(tvar);
  2194                      l.nonEmpty();
  2195                      l = l.tail) {
  2196                     if (rank(l.head) > r) r = rank(l.head);
  2198                 tvar.rank_field = r + 1;
  2200             return tvar.rank_field;
  2202         case ERROR:
  2203             return 0;
  2204         default:
  2205             throw new AssertionError();
  2208     // </editor-fold>
  2210     // <editor-fold defaultstate="collapsed" desc="toString">
  2211     /**
  2212      * This toString is slightly more descriptive than the one on Type.
  2213      */
  2214     public String toString(Type t) {
  2215         if (t.tag == FORALL) {
  2216             ForAll forAll = (ForAll)t;
  2217             return typaramsString(forAll.tvars) + forAll.qtype;
  2219         return "" + t;
  2221     // where
  2222         private String typaramsString(List<Type> tvars) {
  2223             StringBuffer s = new StringBuffer();
  2224             s.append('<');
  2225             boolean first = true;
  2226             for (Type t : tvars) {
  2227                 if (!first) s.append(", ");
  2228                 first = false;
  2229                 appendTyparamString(((TypeVar)t), s);
  2231             s.append('>');
  2232             return s.toString();
  2234         private void appendTyparamString(TypeVar t, StringBuffer buf) {
  2235             buf.append(t);
  2236             if (t.bound == null ||
  2237                 t.bound.tsym.getQualifiedName() == names.java_lang_Object)
  2238                 return;
  2239             buf.append(" extends "); // Java syntax; no need for i18n
  2240             Type bound = t.bound;
  2241             if (!bound.isCompound()) {
  2242                 buf.append(bound);
  2243             } else if ((erasure(t).tsym.flags() & INTERFACE) == 0) {
  2244                 buf.append(supertype(t));
  2245                 for (Type intf : interfaces(t)) {
  2246                     buf.append('&');
  2247                     buf.append(intf);
  2249             } else {
  2250                 // No superclass was given in bounds.
  2251                 // In this case, supertype is Object, erasure is first interface.
  2252                 boolean first = true;
  2253                 for (Type intf : interfaces(t)) {
  2254                     if (!first) buf.append('&');
  2255                     first = false;
  2256                     buf.append(intf);
  2260     // </editor-fold>
  2262     // <editor-fold defaultstate="collapsed" desc="Determining least upper bounds of types">
  2263     /**
  2264      * A cache for closures.
  2266      * <p>A closure is a list of all the supertypes and interfaces of
  2267      * a class or interface type, ordered by ClassSymbol.precedes
  2268      * (that is, subclasses come first, arbitrary but fixed
  2269      * otherwise).
  2270      */
  2271     private Map<Type,List<Type>> closureCache = new HashMap<Type,List<Type>>();
  2273     /**
  2274      * Returns the closure of a class or interface type.
  2275      */
  2276     public List<Type> closure(Type t) {
  2277         List<Type> cl = closureCache.get(t);
  2278         if (cl == null) {
  2279             Type st = supertype(t);
  2280             if (!t.isCompound()) {
  2281                 if (st.tag == CLASS) {
  2282                     cl = insert(closure(st), t);
  2283                 } else if (st.tag == TYPEVAR) {
  2284                     cl = closure(st).prepend(t);
  2285                 } else {
  2286                     cl = List.of(t);
  2288             } else {
  2289                 cl = closure(supertype(t));
  2291             for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail)
  2292                 cl = union(cl, closure(l.head));
  2293             closureCache.put(t, cl);
  2295         return cl;
  2298     /**
  2299      * Insert a type in a closure
  2300      */
  2301     public List<Type> insert(List<Type> cl, Type t) {
  2302         if (cl.isEmpty() || t.tsym.precedes(cl.head.tsym, this)) {
  2303             return cl.prepend(t);
  2304         } else if (cl.head.tsym.precedes(t.tsym, this)) {
  2305             return insert(cl.tail, t).prepend(cl.head);
  2306         } else {
  2307             return cl;
  2311     /**
  2312      * Form the union of two closures
  2313      */
  2314     public List<Type> union(List<Type> cl1, List<Type> cl2) {
  2315         if (cl1.isEmpty()) {
  2316             return cl2;
  2317         } else if (cl2.isEmpty()) {
  2318             return cl1;
  2319         } else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) {
  2320             return union(cl1.tail, cl2).prepend(cl1.head);
  2321         } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) {
  2322             return union(cl1, cl2.tail).prepend(cl2.head);
  2323         } else {
  2324             return union(cl1.tail, cl2.tail).prepend(cl1.head);
  2328     /**
  2329      * Intersect two closures
  2330      */
  2331     public List<Type> intersect(List<Type> cl1, List<Type> cl2) {
  2332         if (cl1 == cl2)
  2333             return cl1;
  2334         if (cl1.isEmpty() || cl2.isEmpty())
  2335             return List.nil();
  2336         if (cl1.head.tsym.precedes(cl2.head.tsym, this))
  2337             return intersect(cl1.tail, cl2);
  2338         if (cl2.head.tsym.precedes(cl1.head.tsym, this))
  2339             return intersect(cl1, cl2.tail);
  2340         if (isSameType(cl1.head, cl2.head))
  2341             return intersect(cl1.tail, cl2.tail).prepend(cl1.head);
  2342         if (cl1.head.tsym == cl2.head.tsym &&
  2343             cl1.head.tag == CLASS && cl2.head.tag == CLASS) {
  2344             if (cl1.head.isParameterized() && cl2.head.isParameterized()) {
  2345                 Type merge = merge(cl1.head,cl2.head);
  2346                 return intersect(cl1.tail, cl2.tail).prepend(merge);
  2348             if (cl1.head.isRaw() || cl2.head.isRaw())
  2349                 return intersect(cl1.tail, cl2.tail).prepend(erasure(cl1.head));
  2351         return intersect(cl1.tail, cl2.tail);
  2353     // where
  2354         class TypePair {
  2355             final Type t1;
  2356             final Type t2;
  2357             TypePair(Type t1, Type t2) {
  2358                 this.t1 = t1;
  2359                 this.t2 = t2;
  2361             @Override
  2362             public int hashCode() {
  2363                 return 127 * Types.this.hashCode(t1) + Types.this.hashCode(t2);
  2365             @Override
  2366             public boolean equals(Object obj) {
  2367                 if (!(obj instanceof TypePair))
  2368                     return false;
  2369                 TypePair typePair = (TypePair)obj;
  2370                 return isSameType(t1, typePair.t1)
  2371                     && isSameType(t2, typePair.t2);
  2374         Set<TypePair> mergeCache = new HashSet<TypePair>();
  2375         private Type merge(Type c1, Type c2) {
  2376             ClassType class1 = (ClassType) c1;
  2377             List<Type> act1 = class1.getTypeArguments();
  2378             ClassType class2 = (ClassType) c2;
  2379             List<Type> act2 = class2.getTypeArguments();
  2380             ListBuffer<Type> merged = new ListBuffer<Type>();
  2381             List<Type> typarams = class1.tsym.type.getTypeArguments();
  2383             while (act1.nonEmpty() && act2.nonEmpty() && typarams.nonEmpty()) {
  2384                 if (containsType(act1.head, act2.head)) {
  2385                     merged.append(act1.head);
  2386                 } else if (containsType(act2.head, act1.head)) {
  2387                     merged.append(act2.head);
  2388                 } else {
  2389                     TypePair pair = new TypePair(c1, c2);
  2390                     Type m;
  2391                     if (mergeCache.add(pair)) {
  2392                         m = new WildcardType(lub(upperBound(act1.head),
  2393                                                  upperBound(act2.head)),
  2394                                              BoundKind.EXTENDS,
  2395                                              syms.boundClass);
  2396                         mergeCache.remove(pair);
  2397                     } else {
  2398                         m = new WildcardType(syms.objectType,
  2399                                              BoundKind.UNBOUND,
  2400                                              syms.boundClass);
  2402                     merged.append(m.withTypeVar(typarams.head));
  2404                 act1 = act1.tail;
  2405                 act2 = act2.tail;
  2406                 typarams = typarams.tail;
  2408             assert(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
  2409             return new ClassType(class1.getEnclosingType(), merged.toList(), class1.tsym);
  2412     /**
  2413      * Return the minimum type of a closure, a compound type if no
  2414      * unique minimum exists.
  2415      */
  2416     private Type compoundMin(List<Type> cl) {
  2417         if (cl.isEmpty()) return syms.objectType;
  2418         List<Type> compound = closureMin(cl);
  2419         if (compound.isEmpty())
  2420             return null;
  2421         else if (compound.tail.isEmpty())
  2422             return compound.head;
  2423         else
  2424             return makeCompoundType(compound);
  2427     /**
  2428      * Return the minimum types of a closure, suitable for computing
  2429      * compoundMin or glb.
  2430      */
  2431     private List<Type> closureMin(List<Type> cl) {
  2432         ListBuffer<Type> classes = lb();
  2433         ListBuffer<Type> interfaces = lb();
  2434         while (!cl.isEmpty()) {
  2435             Type current = cl.head;
  2436             if (current.isInterface())
  2437                 interfaces.append(current);
  2438             else
  2439                 classes.append(current);
  2440             ListBuffer<Type> candidates = lb();
  2441             for (Type t : cl.tail) {
  2442                 if (!isSubtypeNoCapture(current, t))
  2443                     candidates.append(t);
  2445             cl = candidates.toList();
  2447         return classes.appendList(interfaces).toList();
  2450     /**
  2451      * Return the least upper bound of pair of types.  if the lub does
  2452      * not exist return null.
  2453      */
  2454     public Type lub(Type t1, Type t2) {
  2455         return lub(List.of(t1, t2));
  2458     /**
  2459      * Return the least upper bound (lub) of set of types.  If the lub
  2460      * does not exist return the type of null (bottom).
  2461      */
  2462     public Type lub(List<Type> ts) {
  2463         final int ARRAY_BOUND = 1;
  2464         final int CLASS_BOUND = 2;
  2465         int boundkind = 0;
  2466         for (Type t : ts) {
  2467             switch (t.tag) {
  2468             case CLASS:
  2469                 boundkind |= CLASS_BOUND;
  2470                 break;
  2471             case ARRAY:
  2472                 boundkind |= ARRAY_BOUND;
  2473                 break;
  2474             case  TYPEVAR:
  2475                 do {
  2476                     t = t.getUpperBound();
  2477                 } while (t.tag == TYPEVAR);
  2478                 if (t.tag == ARRAY) {
  2479                     boundkind |= ARRAY_BOUND;
  2480                 } else {
  2481                     boundkind |= CLASS_BOUND;
  2483                 break;
  2484             default:
  2485                 if (t.isPrimitive())
  2486                     return syms.botType;
  2489         switch (boundkind) {
  2490         case 0:
  2491             return syms.botType;
  2493         case ARRAY_BOUND:
  2494             // calculate lub(A[], B[])
  2495             List<Type> elements = Type.map(ts, elemTypeFun);
  2496             for (Type t : elements) {
  2497                 if (t.isPrimitive()) {
  2498                     // if a primitive type is found, then return
  2499                     // arraySuperType unless all the types are the
  2500                     // same
  2501                     Type first = ts.head;
  2502                     for (Type s : ts.tail) {
  2503                         if (!isSameType(first, s)) {
  2504                              // lub(int[], B[]) is Cloneable & Serializable
  2505                             return arraySuperType();
  2508                     // all the array types are the same, return one
  2509                     // lub(int[], int[]) is int[]
  2510                     return first;
  2513             // lub(A[], B[]) is lub(A, B)[]
  2514             return new ArrayType(lub(elements), syms.arrayClass);
  2516         case CLASS_BOUND:
  2517             // calculate lub(A, B)
  2518             while (ts.head.tag != CLASS && ts.head.tag != TYPEVAR)
  2519                 ts = ts.tail;
  2520             assert !ts.isEmpty();
  2521             List<Type> cl = closure(ts.head);
  2522             for (Type t : ts.tail) {
  2523                 if (t.tag == CLASS || t.tag == TYPEVAR)
  2524                     cl = intersect(cl, closure(t));
  2526             return compoundMin(cl);
  2528         default:
  2529             // calculate lub(A, B[])
  2530             List<Type> classes = List.of(arraySuperType());
  2531             for (Type t : ts) {
  2532                 if (t.tag != ARRAY) // Filter out any arrays
  2533                     classes = classes.prepend(t);
  2535             // lub(A, B[]) is lub(A, arraySuperType)
  2536             return lub(classes);
  2539     // where
  2540         private Type arraySuperType = null;
  2541         private Type arraySuperType() {
  2542             // initialized lazily to avoid problems during compiler startup
  2543             if (arraySuperType == null) {
  2544                 synchronized (this) {
  2545                     if (arraySuperType == null) {
  2546                         // JLS 10.8: all arrays implement Cloneable and Serializable.
  2547                         arraySuperType = makeCompoundType(List.of(syms.serializableType,
  2548                                                                   syms.cloneableType),
  2549                                                           syms.objectType);
  2553             return arraySuperType;
  2555     // </editor-fold>
  2557     // <editor-fold defaultstate="collapsed" desc="Greatest lower bound">
  2558     public Type glb(Type t, Type s) {
  2559         if (s == null)
  2560             return t;
  2561         else if (isSubtypeNoCapture(t, s))
  2562             return t;
  2563         else if (isSubtypeNoCapture(s, t))
  2564             return s;
  2566         List<Type> closure = union(closure(t), closure(s));
  2567         List<Type> bounds = closureMin(closure);
  2569         if (bounds.isEmpty()) {             // length == 0
  2570             return syms.objectType;
  2571         } else if (bounds.tail.isEmpty()) { // length == 1
  2572             return bounds.head;
  2573         } else {                            // length > 1
  2574             int classCount = 0;
  2575             for (Type bound : bounds)
  2576                 if (!bound.isInterface())
  2577                     classCount++;
  2578             if (classCount > 1)
  2579                 return syms.errType;
  2581         return makeCompoundType(bounds);
  2583     // </editor-fold>
  2585     // <editor-fold defaultstate="collapsed" desc="hashCode">
  2586     /**
  2587      * Compute a hash code on a type.
  2588      */
  2589     public static int hashCode(Type t) {
  2590         return hashCode.visit(t);
  2592     // where
  2593         private static final UnaryVisitor<Integer> hashCode = new UnaryVisitor<Integer>() {
  2595             public Integer visitType(Type t, Void ignored) {
  2596                 return t.tag;
  2599             @Override
  2600             public Integer visitClassType(ClassType t, Void ignored) {
  2601                 int result = visit(t.getEnclosingType());
  2602                 result *= 127;
  2603                 result += t.tsym.flatName().hashCode();
  2604                 for (Type s : t.getTypeArguments()) {
  2605                     result *= 127;
  2606                     result += visit(s);
  2608                 return result;
  2611             @Override
  2612             public Integer visitWildcardType(WildcardType t, Void ignored) {
  2613                 int result = t.kind.hashCode();
  2614                 if (t.type != null) {
  2615                     result *= 127;
  2616                     result += visit(t.type);
  2618                 return result;
  2621             @Override
  2622             public Integer visitArrayType(ArrayType t, Void ignored) {
  2623                 return visit(t.elemtype) + 12;
  2626             @Override
  2627             public Integer visitTypeVar(TypeVar t, Void ignored) {
  2628                 return System.identityHashCode(t.tsym);
  2631             @Override
  2632             public Integer visitUndetVar(UndetVar t, Void ignored) {
  2633                 return System.identityHashCode(t);
  2636             @Override
  2637             public Integer visitErrorType(ErrorType t, Void ignored) {
  2638                 return 0;
  2640         };
  2641     // </editor-fold>
  2643     // <editor-fold defaultstate="collapsed" desc="Return-Type-Substitutable">
  2644     /**
  2645      * Does t have a result that is a subtype of the result type of s,
  2646      * suitable for covariant returns?  It is assumed that both types
  2647      * are (possibly polymorphic) method types.  Monomorphic method
  2648      * types are handled in the obvious way.  Polymorphic method types
  2649      * require renaming all type variables of one to corresponding
  2650      * type variables in the other, where correspondence is by
  2651      * position in the type parameter list. */
  2652     public boolean resultSubtype(Type t, Type s, Warner warner) {
  2653         List<Type> tvars = t.getTypeArguments();
  2654         List<Type> svars = s.getTypeArguments();
  2655         Type tres = t.getReturnType();
  2656         Type sres = subst(s.getReturnType(), svars, tvars);
  2657         return covariantReturnType(tres, sres, warner);
  2660     /**
  2661      * Return-Type-Substitutable.
  2662      * @see <a href="http://java.sun.com/docs/books/jls/">The Java
  2663      * Language Specification, Third Ed. (8.4.5)</a>
  2664      */
  2665     public boolean returnTypeSubstitutable(Type r1, Type r2) {
  2666         if (hasSameArgs(r1, r2))
  2667             return resultSubtype(r1, r2, Warner.noWarnings);
  2668         else
  2669             return covariantReturnType(r1.getReturnType(),
  2670                                        erasure(r2.getReturnType()),
  2671                                        Warner.noWarnings);
  2674     public boolean returnTypeSubstitutable(Type r1,
  2675                                            Type r2, Type r2res,
  2676                                            Warner warner) {
  2677         if (isSameType(r1.getReturnType(), r2res))
  2678             return true;
  2679         if (r1.getReturnType().isPrimitive() || r2res.isPrimitive())
  2680             return false;
  2682         if (hasSameArgs(r1, r2))
  2683             return covariantReturnType(r1.getReturnType(), r2res, warner);
  2684         if (!source.allowCovariantReturns())
  2685             return false;
  2686         if (isSubtypeUnchecked(r1.getReturnType(), r2res, warner))
  2687             return true;
  2688         if (!isSubtype(r1.getReturnType(), erasure(r2res)))
  2689             return false;
  2690         warner.warnUnchecked();
  2691         return true;
  2694     /**
  2695      * Is t an appropriate return type in an overrider for a
  2696      * method that returns s?
  2697      */
  2698     public boolean covariantReturnType(Type t, Type s, Warner warner) {
  2699         return
  2700             isSameType(t, s) ||
  2701             source.allowCovariantReturns() &&
  2702             !t.isPrimitive() &&
  2703             !s.isPrimitive() &&
  2704             isAssignable(t, s, warner);
  2706     // </editor-fold>
  2708     // <editor-fold defaultstate="collapsed" desc="Box/unbox support">
  2709     /**
  2710      * Return the class that boxes the given primitive.
  2711      */
  2712     public ClassSymbol boxedClass(Type t) {
  2713         return reader.enterClass(syms.boxedName[t.tag]);
  2716     /**
  2717      * Return the primitive type corresponding to a boxed type.
  2718      */
  2719     public Type unboxedType(Type t) {
  2720         if (allowBoxing) {
  2721             for (int i=0; i<syms.boxedName.length; i++) {
  2722                 Name box = syms.boxedName[i];
  2723                 if (box != null &&
  2724                     asSuper(t, reader.enterClass(box)) != null)
  2725                     return syms.typeOfTag[i];
  2728         return Type.noType;
  2730     // </editor-fold>
  2732     // <editor-fold defaultstate="collapsed" desc="Capture conversion">
  2733     /*
  2734      * JLS 3rd Ed. 5.1.10 Capture Conversion:
  2736      * Let G name a generic type declaration with n formal type
  2737      * parameters A1 ... An with corresponding bounds U1 ... Un. There
  2738      * exists a capture conversion from G<T1 ... Tn> to G<S1 ... Sn>,
  2739      * where, for 1 <= i <= n:
  2741      * + If Ti is a wildcard type argument (4.5.1) of the form ? then
  2742      *   Si is a fresh type variable whose upper bound is
  2743      *   Ui[A1 := S1, ..., An := Sn] and whose lower bound is the null
  2744      *   type.
  2746      * + If Ti is a wildcard type argument of the form ? extends Bi,
  2747      *   then Si is a fresh type variable whose upper bound is
  2748      *   glb(Bi, Ui[A1 := S1, ..., An := Sn]) and whose lower bound is
  2749      *   the null type, where glb(V1,... ,Vm) is V1 & ... & Vm. It is
  2750      *   a compile-time error if for any two classes (not interfaces)
  2751      *   Vi and Vj,Vi is not a subclass of Vj or vice versa.
  2753      * + If Ti is a wildcard type argument of the form ? super Bi,
  2754      *   then Si is a fresh type variable whose upper bound is
  2755      *   Ui[A1 := S1, ..., An := Sn] and whose lower bound is Bi.
  2757      * + Otherwise, Si = Ti.
  2759      * Capture conversion on any type other than a parameterized type
  2760      * (4.5) acts as an identity conversion (5.1.1). Capture
  2761      * conversions never require a special action at run time and
  2762      * therefore never throw an exception at run time.
  2764      * Capture conversion is not applied recursively.
  2765      */
  2766     /**
  2767      * Capture conversion as specified by JLS 3rd Ed.
  2768      */
  2769     public Type capture(Type t) {
  2770         if (t.tag != CLASS)
  2771             return t;
  2772         ClassType cls = (ClassType)t;
  2773         if (cls.isRaw() || !cls.isParameterized())
  2774             return cls;
  2776         ClassType G = (ClassType)cls.asElement().asType();
  2777         List<Type> A = G.getTypeArguments();
  2778         List<Type> T = cls.getTypeArguments();
  2779         List<Type> S = freshTypeVariables(T);
  2781         List<Type> currentA = A;
  2782         List<Type> currentT = T;
  2783         List<Type> currentS = S;
  2784         boolean captured = false;
  2785         while (!currentA.isEmpty() &&
  2786                !currentT.isEmpty() &&
  2787                !currentS.isEmpty()) {
  2788             if (currentS.head != currentT.head) {
  2789                 captured = true;
  2790                 WildcardType Ti = (WildcardType)currentT.head;
  2791                 Type Ui = currentA.head.getUpperBound();
  2792                 CapturedType Si = (CapturedType)currentS.head;
  2793                 if (Ui == null)
  2794                     Ui = syms.objectType;
  2795                 switch (Ti.kind) {
  2796                 case UNBOUND:
  2797                     Si.bound = subst(Ui, A, S);
  2798                     Si.lower = syms.botType;
  2799                     break;
  2800                 case EXTENDS:
  2801                     Si.bound = glb(Ti.getExtendsBound(), subst(Ui, A, S));
  2802                     Si.lower = syms.botType;
  2803                     break;
  2804                 case SUPER:
  2805                     Si.bound = subst(Ui, A, S);
  2806                     Si.lower = Ti.getSuperBound();
  2807                     break;
  2809                 if (Si.bound == Si.lower)
  2810                     currentS.head = Si.bound;
  2812             currentA = currentA.tail;
  2813             currentT = currentT.tail;
  2814             currentS = currentS.tail;
  2816         if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty())
  2817             return erasure(t); // some "rare" type involved
  2819         if (captured)
  2820             return new ClassType(cls.getEnclosingType(), S, cls.tsym);
  2821         else
  2822             return t;
  2824     // where
  2825         private List<Type> freshTypeVariables(List<Type> types) {
  2826             ListBuffer<Type> result = lb();
  2827             for (Type t : types) {
  2828                 if (t.tag == WILDCARD) {
  2829                     Type bound = ((WildcardType)t).getExtendsBound();
  2830                     if (bound == null)
  2831                         bound = syms.objectType;
  2832                     result.append(new CapturedType(capturedName,
  2833                                                    syms.noSymbol,
  2834                                                    bound,
  2835                                                    syms.botType,
  2836                                                    (WildcardType)t));
  2837                 } else {
  2838                     result.append(t);
  2841             return result.toList();
  2843     // </editor-fold>
  2845     // <editor-fold defaultstate="collapsed" desc="Internal utility methods">
  2846     private List<Type> upperBounds(List<Type> ss) {
  2847         if (ss.isEmpty()) return ss;
  2848         Type head = upperBound(ss.head);
  2849         List<Type> tail = upperBounds(ss.tail);
  2850         if (head != ss.head || tail != ss.tail)
  2851             return tail.prepend(head);
  2852         else
  2853             return ss;
  2856     private boolean sideCast(Type from, Type to, Warner warn) {
  2857         // We are casting from type $from$ to type $to$, which are
  2858         // non-final unrelated types.  This method
  2859         // tries to reject a cast by transferring type parameters
  2860         // from $to$ to $from$ by common superinterfaces.
  2861         boolean reverse = false;
  2862         Type target = to;
  2863         if ((to.tsym.flags() & INTERFACE) == 0) {
  2864             assert (from.tsym.flags() & INTERFACE) != 0;
  2865             reverse = true;
  2866             to = from;
  2867             from = target;
  2869         List<Type> commonSupers = superClosure(to, erasure(from));
  2870         boolean giveWarning = commonSupers.isEmpty();
  2871         // The arguments to the supers could be unified here to
  2872         // get a more accurate analysis
  2873         while (commonSupers.nonEmpty()) {
  2874             Type t1 = asSuper(from, commonSupers.head.tsym);
  2875             Type t2 = commonSupers.head; // same as asSuper(to, commonSupers.head.tsym);
  2876             if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
  2877                 return false;
  2878             giveWarning = giveWarning || (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2));
  2879             commonSupers = commonSupers.tail;
  2881         if (giveWarning && !isReifiable(to))
  2882             warn.warnUnchecked();
  2883         if (!source.allowCovariantReturns())
  2884             // reject if there is a common method signature with
  2885             // incompatible return types.
  2886             chk.checkCompatibleAbstracts(warn.pos(), from, to);
  2887         return true;
  2890     private boolean sideCastFinal(Type from, Type to, Warner warn) {
  2891         // We are casting from type $from$ to type $to$, which are
  2892         // unrelated types one of which is final and the other of
  2893         // which is an interface.  This method
  2894         // tries to reject a cast by transferring type parameters
  2895         // from the final class to the interface.
  2896         boolean reverse = false;
  2897         Type target = to;
  2898         if ((to.tsym.flags() & INTERFACE) == 0) {
  2899             assert (from.tsym.flags() & INTERFACE) != 0;
  2900             reverse = true;
  2901             to = from;
  2902             from = target;
  2904         assert (from.tsym.flags() & FINAL) != 0;
  2905         Type t1 = asSuper(from, to.tsym);
  2906         if (t1 == null) return false;
  2907         Type t2 = to;
  2908         if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
  2909             return false;
  2910         if (!source.allowCovariantReturns())
  2911             // reject if there is a common method signature with
  2912             // incompatible return types.
  2913             chk.checkCompatibleAbstracts(warn.pos(), from, to);
  2914         if (!isReifiable(target) &&
  2915             (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2)))
  2916             warn.warnUnchecked();
  2917         return true;
  2920     private boolean giveWarning(Type from, Type to) {
  2921         // To and from are (possibly different) parameterizations
  2922         // of the same class or interface
  2923         return to.isParameterized() && !containsType(to.getTypeArguments(), from.getTypeArguments());
  2926     private List<Type> superClosure(Type t, Type s) {
  2927         List<Type> cl = List.nil();
  2928         for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
  2929             if (isSubtype(s, erasure(l.head))) {
  2930                 cl = insert(cl, l.head);
  2931             } else {
  2932                 cl = union(cl, superClosure(l.head, s));
  2935         return cl;
  2938     private boolean containsTypeEquivalent(Type t, Type s) {
  2939         return
  2940             isSameType(t, s) || // shortcut
  2941             containsType(t, s) && containsType(s, t);
  2944     /**
  2945      * Adapt a type by computing a substitution which maps a source
  2946      * type to a target type.
  2948      * @param source    the source type
  2949      * @param target    the target type
  2950      * @param from      the type variables of the computed substitution
  2951      * @param to        the types of the computed substitution.
  2952      */
  2953     public void adapt(Type source,
  2954                        Type target,
  2955                        ListBuffer<Type> from,
  2956                        ListBuffer<Type> to) throws AdaptFailure {
  2957         Map<Symbol,Type> mapping = new HashMap<Symbol,Type>();
  2958         adaptRecursive(source, target, from, to, mapping);
  2959         List<Type> fromList = from.toList();
  2960         List<Type> toList = to.toList();
  2961         while (!fromList.isEmpty()) {
  2962             Type val = mapping.get(fromList.head.tsym);
  2963             if (toList.head != val)
  2964                 toList.head = val;
  2965             fromList = fromList.tail;
  2966             toList = toList.tail;
  2969     // where
  2970         private void adaptRecursive(Type source,
  2971                                     Type target,
  2972                                     ListBuffer<Type> from,
  2973                                     ListBuffer<Type> to,
  2974                                     Map<Symbol,Type> mapping) throws AdaptFailure {
  2975             if (source.tag == TYPEVAR) {
  2976                 // Check to see if there is
  2977                 // already a mapping for $source$, in which case
  2978                 // the old mapping will be merged with the new
  2979                 Type val = mapping.get(source.tsym);
  2980                 if (val != null) {
  2981                     if (val.isSuperBound() && target.isSuperBound()) {
  2982                         val = isSubtype(lowerBound(val), lowerBound(target))
  2983                             ? target : val;
  2984                     } else if (val.isExtendsBound() && target.isExtendsBound()) {
  2985                         val = isSubtype(upperBound(val), upperBound(target))
  2986                             ? val : target;
  2987                     } else if (!isSameType(val, target)) {
  2988                         throw new AdaptFailure();
  2990                 } else {
  2991                     val = target;
  2992                     from.append(source);
  2993                     to.append(target);
  2995                 mapping.put(source.tsym, val);
  2996             } else if (source.tag == target.tag) {
  2997                 switch (source.tag) {
  2998                     case CLASS:
  2999                         adapt(source.allparams(), target.allparams(),
  3000                               from, to, mapping);
  3001                         break;
  3002                     case ARRAY:
  3003                         adaptRecursive(elemtype(source), elemtype(target),
  3004                                        from, to, mapping);
  3005                         break;
  3006                     case WILDCARD:
  3007                         if (source.isExtendsBound()) {
  3008                             adaptRecursive(upperBound(source), upperBound(target),
  3009                                            from, to, mapping);
  3010                         } else if (source.isSuperBound()) {
  3011                             adaptRecursive(lowerBound(source), lowerBound(target),
  3012                                            from, to, mapping);
  3014                         break;
  3018         public static class AdaptFailure extends Exception {
  3019             static final long serialVersionUID = -7490231548272701566L;
  3022     /**
  3023      * Adapt a type by computing a substitution which maps a list of
  3024      * source types to a list of target types.
  3026      * @param source    the source type
  3027      * @param target    the target type
  3028      * @param from      the type variables of the computed substitution
  3029      * @param to        the types of the computed substitution.
  3030      */
  3031     private void adapt(List<Type> source,
  3032                        List<Type> target,
  3033                        ListBuffer<Type> from,
  3034                        ListBuffer<Type> to,
  3035                        Map<Symbol,Type> mapping) throws AdaptFailure {
  3036         if (source.length() == target.length()) {
  3037             while (source.nonEmpty()) {
  3038                 adaptRecursive(source.head, target.head, from, to, mapping);
  3039                 source = source.tail;
  3040                 target = target.tail;
  3045     private void adaptSelf(Type t,
  3046                            ListBuffer<Type> from,
  3047                            ListBuffer<Type> to) {
  3048         try {
  3049             //if (t.tsym.type != t)
  3050                 adapt(t.tsym.type, t, from, to);
  3051         } catch (AdaptFailure ex) {
  3052             // Adapt should never fail calculating a mapping from
  3053             // t.tsym.type to t as there can be no merge problem.
  3054             throw new AssertionError(ex);
  3058     /**
  3059      * Rewrite all type variables (universal quantifiers) in the given
  3060      * type to wildcards (existential quantifiers).  This is used to
  3061      * determine if a cast is allowed.  For example, if high is true
  3062      * and {@code T <: Number}, then {@code List<T>} is rewritten to
  3063      * {@code List<?  extends Number>}.  Since {@code List<Integer> <:
  3064      * List<? extends Number>} a {@code List<T>} can be cast to {@code
  3065      * List<Integer>} with a warning.
  3066      * @param t a type
  3067      * @param high if true return an upper bound; otherwise a lower
  3068      * bound
  3069      * @param rewriteTypeVars only rewrite captured wildcards if false;
  3070      * otherwise rewrite all type variables
  3071      * @return the type rewritten with wildcards (existential
  3072      * quantifiers) only
  3073      */
  3074     private Type rewriteQuantifiers(Type t, boolean high, boolean rewriteTypeVars) {
  3075         ListBuffer<Type> from = new ListBuffer<Type>();
  3076         ListBuffer<Type> to = new ListBuffer<Type>();
  3077         adaptSelf(t, from, to);
  3078         ListBuffer<Type> rewritten = new ListBuffer<Type>();
  3079         List<Type> formals = from.toList();
  3080         boolean changed = false;
  3081         for (Type arg : to.toList()) {
  3082             Type bound;
  3083             if (rewriteTypeVars && arg.tag == TYPEVAR) {
  3084                 TypeVar tv = (TypeVar)arg;
  3085                 bound = high ? tv.bound : syms.botType;
  3086             } else {
  3087                 bound = high ? upperBound(arg) : lowerBound(arg);
  3089             Type newarg = bound;
  3090             if (arg != bound) {
  3091                 changed = true;
  3092                 newarg = high ? makeExtendsWildcard(bound, (TypeVar)formals.head)
  3093                               : makeSuperWildcard(bound, (TypeVar)formals.head);
  3095             rewritten.append(newarg);
  3096             formals = formals.tail;
  3098         if (changed)
  3099             return subst(t.tsym.type, from.toList(), rewritten.toList());
  3100         else
  3101             return t;
  3104     /**
  3105      * Create a wildcard with the given upper (extends) bound; create
  3106      * an unbounded wildcard if bound is Object.
  3108      * @param bound the upper bound
  3109      * @param formal the formal type parameter that will be
  3110      * substituted by the wildcard
  3111      */
  3112     private WildcardType makeExtendsWildcard(Type bound, TypeVar formal) {
  3113         if (bound == syms.objectType) {
  3114             return new WildcardType(syms.objectType,
  3115                                     BoundKind.UNBOUND,
  3116                                     syms.boundClass,
  3117                                     formal);
  3118         } else {
  3119             return new WildcardType(bound,
  3120                                     BoundKind.EXTENDS,
  3121                                     syms.boundClass,
  3122                                     formal);
  3126     /**
  3127      * Create a wildcard with the given lower (super) bound; create an
  3128      * unbounded wildcard if bound is bottom (type of {@code null}).
  3130      * @param bound the lower bound
  3131      * @param formal the formal type parameter that will be
  3132      * substituted by the wildcard
  3133      */
  3134     private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
  3135         if (bound.tag == BOT) {
  3136             return new WildcardType(syms.objectType,
  3137                                     BoundKind.UNBOUND,
  3138                                     syms.boundClass,
  3139                                     formal);
  3140         } else {
  3141             return new WildcardType(bound,
  3142                                     BoundKind.SUPER,
  3143                                     syms.boundClass,
  3144                                     formal);
  3148     /**
  3149      * A wrapper for a type that allows use in sets.
  3150      */
  3151     class SingletonType {
  3152         final Type t;
  3153         SingletonType(Type t) {
  3154             this.t = t;
  3156         public int hashCode() {
  3157             return Types.this.hashCode(t);
  3159         public boolean equals(Object obj) {
  3160             return (obj instanceof SingletonType) &&
  3161                 isSameType(t, ((SingletonType)obj).t);
  3163         public String toString() {
  3164             return t.toString();
  3167     // </editor-fold>
  3169     // <editor-fold defaultstate="collapsed" desc="Visitors">
  3170     /**
  3171      * A default visitor for types.  All visitor methods except
  3172      * visitType are implemented by delegating to visitType.  Concrete
  3173      * subclasses must provide an implementation of visitType and can
  3174      * override other methods as needed.
  3176      * @param <R> the return type of the operation implemented by this
  3177      * visitor; use Void if no return type is needed.
  3178      * @param <S> the type of the second argument (the first being the
  3179      * type itself) of the operation implemented by this visitor; use
  3180      * Void if a second argument is not needed.
  3181      */
  3182     public static abstract class DefaultTypeVisitor<R,S> implements Type.Visitor<R,S> {
  3183         final public R visit(Type t, S s)               { return t.accept(this, s); }
  3184         public R visitClassType(ClassType t, S s)       { return visitType(t, s); }
  3185         public R visitWildcardType(WildcardType t, S s) { return visitType(t, s); }
  3186         public R visitArrayType(ArrayType t, S s)       { return visitType(t, s); }
  3187         public R visitMethodType(MethodType t, S s)     { return visitType(t, s); }
  3188         public R visitPackageType(PackageType t, S s)   { return visitType(t, s); }
  3189         public R visitTypeVar(TypeVar t, S s)           { return visitType(t, s); }
  3190         public R visitCapturedType(CapturedType t, S s) { return visitType(t, s); }
  3191         public R visitForAll(ForAll t, S s)             { return visitType(t, s); }
  3192         public R visitUndetVar(UndetVar t, S s)         { return visitType(t, s); }
  3193         public R visitErrorType(ErrorType t, S s)       { return visitType(t, s); }
  3196     /**
  3197      * A <em>simple</em> visitor for types.  This visitor is simple as
  3198      * captured wildcards, for-all types (generic methods), and
  3199      * undetermined type variables (part of inference) are hidden.
  3200      * Captured wildcards are hidden by treating them as type
  3201      * variables and the rest are hidden by visiting their qtypes.
  3203      * @param <R> the return type of the operation implemented by this
  3204      * visitor; use Void if no return type is needed.
  3205      * @param <S> the type of the second argument (the first being the
  3206      * type itself) of the operation implemented by this visitor; use
  3207      * Void if a second argument is not needed.
  3208      */
  3209     public static abstract class SimpleVisitor<R,S> extends DefaultTypeVisitor<R,S> {
  3210         @Override
  3211         public R visitCapturedType(CapturedType t, S s) {
  3212             return visitTypeVar(t, s);
  3214         @Override
  3215         public R visitForAll(ForAll t, S s) {
  3216             return visit(t.qtype, s);
  3218         @Override
  3219         public R visitUndetVar(UndetVar t, S s) {
  3220             return visit(t.qtype, s);
  3224     /**
  3225      * A plain relation on types.  That is a 2-ary function on the
  3226      * form Type&nbsp;&times;&nbsp;Type&nbsp;&rarr;&nbsp;Boolean.
  3227      * <!-- In plain text: Type x Type -> Boolean -->
  3228      */
  3229     public static abstract class TypeRelation extends SimpleVisitor<Boolean,Type> {}
  3231     /**
  3232      * A convenience visitor for implementing operations that only
  3233      * require one argument (the type itself), that is, unary
  3234      * operations.
  3236      * @param <R> the return type of the operation implemented by this
  3237      * visitor; use Void if no return type is needed.
  3238      */
  3239     public static abstract class UnaryVisitor<R> extends SimpleVisitor<R,Void> {
  3240         final public R visit(Type t) { return t.accept(this, null); }
  3243     /**
  3244      * A visitor for implementing a mapping from types to types.  The
  3245      * default behavior of this class is to implement the identity
  3246      * mapping (mapping a type to itself).  This can be overridden in
  3247      * subclasses.
  3249      * @param <S> the type of the second argument (the first being the
  3250      * type itself) of this mapping; use Void if a second argument is
  3251      * not needed.
  3252      */
  3253     public static class MapVisitor<S> extends DefaultTypeVisitor<Type,S> {
  3254         final public Type visit(Type t) { return t.accept(this, null); }
  3255         public Type visitType(Type t, S s) { return t; }
  3257     // </editor-fold>

mercurial