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

Thu, 09 Oct 2008 16:07:38 +0100

author
mcimadamore
date
Thu, 09 Oct 2008 16:07:38 +0100
changeset 136
8eafba4f61be
parent 134
8c098cf64ab5
child 138
d766e40e49d6
permissions
-rw-r--r--

6406133: JCDiagnostic.getMessage ignores locale argument
Summary: Compiler API should take into account locale settings
Reviewed-by: jjg

     1 /*
     2  * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Sun designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Sun in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
    23  * have any questions.
    24  */
    26 package com.sun.tools.javac.code;
    28 import java.util.*;
    30 import com.sun.tools.javac.util.*;
    31 import com.sun.tools.javac.util.List;
    33 import com.sun.tools.javac.jvm.ClassReader;
    34 import com.sun.tools.javac.comp.Check;
    36 import static com.sun.tools.javac.code.Type.*;
    37 import static com.sun.tools.javac.code.TypeTags.*;
    38 import static com.sun.tools.javac.code.Symbol.*;
    39 import static com.sun.tools.javac.code.Flags.*;
    40 import static com.sun.tools.javac.code.BoundKind.*;
    41 import static com.sun.tools.javac.util.ListBuffer.lb;
    43 /**
    44  * Utility class containing various operations on types.
    45  *
    46  * <p>Unless other names are more illustrative, the following naming
    47  * conventions should be observed in this file:
    48  *
    49  * <dl>
    50  * <dt>t</dt>
    51  * <dd>If the first argument to an operation is a type, it should be named t.</dd>
    52  * <dt>s</dt>
    53  * <dd>Similarly, if the second argument to an operation is a type, it should be named s.</dd>
    54  * <dt>ts</dt>
    55  * <dd>If an operations takes a list of types, the first should be named ts.</dd>
    56  * <dt>ss</dt>
    57  * <dd>A second list of types should be named ss.</dd>
    58  * </dl>
    59  *
    60  * <p><b>This is NOT part of any API supported by Sun Microsystems.
    61  * If you write code that depends on this, you do so at your own risk.
    62  * This code and its internal interfaces are subject to change or
    63  * deletion without notice.</b>
    64  */
    65 public class Types {
    66     protected static final Context.Key<Types> typesKey =
    67         new Context.Key<Types>();
    69     final Symtab syms;
    70     final JavacMessages messages;
    71     final Names 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 = Names.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         messages = JavacMessages.instance(context);
    97     }
    98     // </editor-fold>
   100     // <editor-fold defaultstate="collapsed" desc="upperBound">
   101     /**
   102      * The "rvalue conversion".<br>
   103      * The upper bound of most types is the type
   104      * itself.  Wildcards, on the other hand have upper
   105      * and lower bounds.
   106      * @param t a type
   107      * @return the upper bound of the given type
   108      */
   109     public Type upperBound(Type t) {
   110         return upperBound.visit(t);
   111     }
   112     // where
   113         private final MapVisitor<Void> upperBound = new MapVisitor<Void>() {
   115             @Override
   116             public Type visitWildcardType(WildcardType t, Void ignored) {
   117                 if (t.isSuperBound())
   118                     return t.bound == null ? syms.objectType : t.bound.bound;
   119                 else
   120                     return visit(t.type);
   121             }
   123             @Override
   124             public Type visitCapturedType(CapturedType t, Void ignored) {
   125                 return visit(t.bound);
   126             }
   127         };
   128     // </editor-fold>
   130     // <editor-fold defaultstate="collapsed" desc="lowerBound">
   131     /**
   132      * The "lvalue conversion".<br>
   133      * The lower bound of most types is the type
   134      * itself.  Wildcards, on the other hand have upper
   135      * and lower bounds.
   136      * @param t a type
   137      * @return the lower bound of the given type
   138      */
   139     public Type lowerBound(Type t) {
   140         return lowerBound.visit(t);
   141     }
   142     // where
   143         private final MapVisitor<Void> lowerBound = new MapVisitor<Void>() {
   145             @Override
   146             public Type visitWildcardType(WildcardType t, Void ignored) {
   147                 return t.isExtendsBound() ? syms.botType : visit(t.type);
   148             }
   150             @Override
   151             public Type visitCapturedType(CapturedType t, Void ignored) {
   152                 return visit(t.getLowerBound());
   153             }
   154         };
   155     // </editor-fold>
   157     // <editor-fold defaultstate="collapsed" desc="isUnbounded">
   158     /**
   159      * Checks that all the arguments to a class are unbounded
   160      * wildcards or something else that doesn't make any restrictions
   161      * on the arguments. If a class isUnbounded, a raw super- or
   162      * subclass can be cast to it without a warning.
   163      * @param t a type
   164      * @return true iff the given type is unbounded or raw
   165      */
   166     public boolean isUnbounded(Type t) {
   167         return isUnbounded.visit(t);
   168     }
   169     // where
   170         private final UnaryVisitor<Boolean> isUnbounded = new UnaryVisitor<Boolean>() {
   172             public Boolean visitType(Type t, Void ignored) {
   173                 return true;
   174             }
   176             @Override
   177             public Boolean visitClassType(ClassType t, Void ignored) {
   178                 List<Type> parms = t.tsym.type.allparams();
   179                 List<Type> args = t.allparams();
   180                 while (parms.nonEmpty()) {
   181                     WildcardType unb = new WildcardType(syms.objectType,
   182                                                         BoundKind.UNBOUND,
   183                                                         syms.boundClass,
   184                                                         (TypeVar)parms.head);
   185                     if (!containsType(args.head, unb))
   186                         return false;
   187                     parms = parms.tail;
   188                     args = args.tail;
   189                 }
   190                 return true;
   191             }
   192         };
   193     // </editor-fold>
   195     // <editor-fold defaultstate="collapsed" desc="asSub">
   196     /**
   197      * Return the least specific subtype of t that starts with symbol
   198      * sym.  If none exists, return null.  The least specific subtype
   199      * is determined as follows:
   200      *
   201      * <p>If there is exactly one parameterized instance of sym that is a
   202      * subtype of t, that parameterized instance is returned.<br>
   203      * Otherwise, if the plain type or raw type `sym' is a subtype of
   204      * type t, the type `sym' itself is returned.  Otherwise, null is
   205      * returned.
   206      */
   207     public Type asSub(Type t, Symbol sym) {
   208         return asSub.visit(t, sym);
   209     }
   210     // where
   211         private final SimpleVisitor<Type,Symbol> asSub = new SimpleVisitor<Type,Symbol>() {
   213             public Type visitType(Type t, Symbol sym) {
   214                 return null;
   215             }
   217             @Override
   218             public Type visitClassType(ClassType t, Symbol sym) {
   219                 if (t.tsym == sym)
   220                     return t;
   221                 Type base = asSuper(sym.type, t.tsym);
   222                 if (base == null)
   223                     return null;
   224                 ListBuffer<Type> from = new ListBuffer<Type>();
   225                 ListBuffer<Type> to = new ListBuffer<Type>();
   226                 try {
   227                     adapt(base, t, from, to);
   228                 } catch (AdaptFailure ex) {
   229                     return null;
   230                 }
   231                 Type res = subst(sym.type, from.toList(), to.toList());
   232                 if (!isSubtype(res, t))
   233                     return null;
   234                 ListBuffer<Type> openVars = new ListBuffer<Type>();
   235                 for (List<Type> l = sym.type.allparams();
   236                      l.nonEmpty(); l = l.tail)
   237                     if (res.contains(l.head) && !t.contains(l.head))
   238                         openVars.append(l.head);
   239                 if (openVars.nonEmpty()) {
   240                     if (t.isRaw()) {
   241                         // The subtype of a raw type is raw
   242                         res = erasure(res);
   243                     } else {
   244                         // Unbound type arguments default to ?
   245                         List<Type> opens = openVars.toList();
   246                         ListBuffer<Type> qs = new ListBuffer<Type>();
   247                         for (List<Type> iter = opens; iter.nonEmpty(); iter = iter.tail) {
   248                             qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head));
   249                         }
   250                         res = subst(res, opens, qs.toList());
   251                     }
   252                 }
   253                 return res;
   254             }
   256             @Override
   257             public Type visitErrorType(ErrorType t, Symbol sym) {
   258                 return t;
   259             }
   260         };
   261     // </editor-fold>
   263     // <editor-fold defaultstate="collapsed" desc="isConvertible">
   264     /**
   265      * Is t a subtype of or convertiable via boxing/unboxing
   266      * convertions to s?
   267      */
   268     public boolean isConvertible(Type t, Type s, Warner warn) {
   269         boolean tPrimitive = t.isPrimitive();
   270         boolean sPrimitive = s.isPrimitive();
   271         if (tPrimitive == sPrimitive)
   272             return isSubtypeUnchecked(t, s, warn);
   273         if (!allowBoxing) return false;
   274         return tPrimitive
   275             ? isSubtype(boxedClass(t).type, s)
   276             : isSubtype(unboxedType(t), s);
   277     }
   279     /**
   280      * Is t a subtype of or convertiable via boxing/unboxing
   281      * convertions to s?
   282      */
   283     public boolean isConvertible(Type t, Type s) {
   284         return isConvertible(t, s, Warner.noWarnings);
   285     }
   286     // </editor-fold>
   288     // <editor-fold defaultstate="collapsed" desc="isSubtype">
   289     /**
   290      * Is t an unchecked subtype of s?
   291      */
   292     public boolean isSubtypeUnchecked(Type t, Type s) {
   293         return isSubtypeUnchecked(t, s, Warner.noWarnings);
   294     }
   295     /**
   296      * Is t an unchecked subtype of s?
   297      */
   298     public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) {
   299         if (t.tag == ARRAY && s.tag == ARRAY) {
   300             return (((ArrayType)t).elemtype.tag <= lastBaseTag)
   301                 ? isSameType(elemtype(t), elemtype(s))
   302                 : isSubtypeUnchecked(elemtype(t), elemtype(s), warn);
   303         } else if (isSubtype(t, s)) {
   304             return true;
   305         }
   306         else if (t.tag == TYPEVAR) {
   307             return isSubtypeUnchecked(t.getUpperBound(), s, warn);
   308         }
   309         else if (s.tag == UNDETVAR) {
   310             UndetVar uv = (UndetVar)s;
   311             if (uv.inst != null)
   312                 return isSubtypeUnchecked(t, uv.inst, warn);
   313         }
   314         else if (!s.isRaw()) {
   315             Type t2 = asSuper(t, s.tsym);
   316             if (t2 != null && t2.isRaw()) {
   317                 if (isReifiable(s))
   318                     warn.silentUnchecked();
   319                 else
   320                     warn.warnUnchecked();
   321                 return true;
   322             }
   323         }
   324         return false;
   325     }
   327     /**
   328      * Is t a subtype of s?<br>
   329      * (not defined for Method and ForAll types)
   330      */
   331     final public boolean isSubtype(Type t, Type s) {
   332         return isSubtype(t, s, true);
   333     }
   334     final public boolean isSubtypeNoCapture(Type t, Type s) {
   335         return isSubtype(t, s, false);
   336     }
   337     public boolean isSubtype(Type t, Type s, boolean capture) {
   338         if (t == s)
   339             return true;
   341         if (s.tag >= firstPartialTag)
   342             return isSuperType(s, t);
   344         Type lower = lowerBound(s);
   345         if (s != lower)
   346             return isSubtype(capture ? capture(t) : t, lower, false);
   348         return isSubtype.visit(capture ? capture(t) : t, s);
   349     }
   350     // where
   351         private TypeRelation isSubtype = new TypeRelation()
   352         {
   353             public Boolean visitType(Type t, Type s) {
   354                 switch (t.tag) {
   355                 case BYTE: case CHAR:
   356                     return (t.tag == s.tag ||
   357                               t.tag + 2 <= s.tag && s.tag <= DOUBLE);
   358                 case SHORT: case INT: case LONG: case FLOAT: case DOUBLE:
   359                     return t.tag <= s.tag && s.tag <= DOUBLE;
   360                 case BOOLEAN: case VOID:
   361                     return t.tag == s.tag;
   362                 case TYPEVAR:
   363                     return isSubtypeNoCapture(t.getUpperBound(), s);
   364                 case BOT:
   365                     return
   366                         s.tag == BOT || s.tag == CLASS ||
   367                         s.tag == ARRAY || s.tag == TYPEVAR;
   368                 case NONE:
   369                     return false;
   370                 default:
   371                     throw new AssertionError("isSubtype " + t.tag);
   372                 }
   373             }
   375             private Set<TypePair> cache = new HashSet<TypePair>();
   377             private boolean containsTypeRecursive(Type t, Type s) {
   378                 TypePair pair = new TypePair(t, s);
   379                 if (cache.add(pair)) {
   380                     try {
   381                         return containsType(t.getTypeArguments(),
   382                                             s.getTypeArguments());
   383                     } finally {
   384                         cache.remove(pair);
   385                     }
   386                 } else {
   387                     return containsType(t.getTypeArguments(),
   388                                         rewriteSupers(s).getTypeArguments());
   389                 }
   390             }
   392             private Type rewriteSupers(Type t) {
   393                 if (!t.isParameterized())
   394                     return t;
   395                 ListBuffer<Type> from = lb();
   396                 ListBuffer<Type> to = lb();
   397                 adaptSelf(t, from, to);
   398                 if (from.isEmpty())
   399                     return t;
   400                 ListBuffer<Type> rewrite = lb();
   401                 boolean changed = false;
   402                 for (Type orig : to.toList()) {
   403                     Type s = rewriteSupers(orig);
   404                     if (s.isSuperBound() && !s.isExtendsBound()) {
   405                         s = new WildcardType(syms.objectType,
   406                                              BoundKind.UNBOUND,
   407                                              syms.boundClass);
   408                         changed = true;
   409                     } else if (s != orig) {
   410                         s = new WildcardType(upperBound(s),
   411                                              BoundKind.EXTENDS,
   412                                              syms.boundClass);
   413                         changed = true;
   414                     }
   415                     rewrite.append(s);
   416                 }
   417                 if (changed)
   418                     return subst(t.tsym.type, from.toList(), rewrite.toList());
   419                 else
   420                     return t;
   421             }
   423             @Override
   424             public Boolean visitClassType(ClassType t, Type s) {
   425                 Type sup = asSuper(t, s.tsym);
   426                 return sup != null
   427                     && sup.tsym == s.tsym
   428                     // You're not allowed to write
   429                     //     Vector<Object> vec = new Vector<String>();
   430                     // But with wildcards you can write
   431                     //     Vector<? extends Object> vec = new Vector<String>();
   432                     // which means that subtype checking must be done
   433                     // here instead of same-type checking (via containsType).
   434                     && (!s.isParameterized() || containsTypeRecursive(s, sup))
   435                     && isSubtypeNoCapture(sup.getEnclosingType(),
   436                                           s.getEnclosingType());
   437             }
   439             @Override
   440             public Boolean visitArrayType(ArrayType t, Type s) {
   441                 if (s.tag == ARRAY) {
   442                     if (t.elemtype.tag <= lastBaseTag)
   443                         return isSameType(t.elemtype, elemtype(s));
   444                     else
   445                         return isSubtypeNoCapture(t.elemtype, elemtype(s));
   446                 }
   448                 if (s.tag == CLASS) {
   449                     Name sname = s.tsym.getQualifiedName();
   450                     return sname == names.java_lang_Object
   451                         || sname == names.java_lang_Cloneable
   452                         || sname == names.java_io_Serializable;
   453                 }
   455                 return false;
   456             }
   458             @Override
   459             public Boolean visitUndetVar(UndetVar t, Type s) {
   460                 //todo: test against origin needed? or replace with substitution?
   461                 if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN)
   462                     return true;
   464                 if (t.inst != null)
   465                     return isSubtypeNoCapture(t.inst, s); // TODO: ", warn"?
   467                 t.hibounds = t.hibounds.prepend(s);
   468                 return true;
   469             }
   471             @Override
   472             public Boolean visitErrorType(ErrorType t, Type s) {
   473                 return true;
   474             }
   475         };
   477     /**
   478      * Is t a subtype of every type in given list `ts'?<br>
   479      * (not defined for Method and ForAll types)<br>
   480      * Allows unchecked conversions.
   481      */
   482     public boolean isSubtypeUnchecked(Type t, List<Type> ts, Warner warn) {
   483         for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
   484             if (!isSubtypeUnchecked(t, l.head, warn))
   485                 return false;
   486         return true;
   487     }
   489     /**
   490      * Are corresponding elements of ts subtypes of ss?  If lists are
   491      * of different length, return false.
   492      */
   493     public boolean isSubtypes(List<Type> ts, List<Type> ss) {
   494         while (ts.tail != null && ss.tail != null
   495                /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
   496                isSubtype(ts.head, ss.head)) {
   497             ts = ts.tail;
   498             ss = ss.tail;
   499         }
   500         return ts.tail == null && ss.tail == null;
   501         /*inlined: ts.isEmpty() && ss.isEmpty();*/
   502     }
   504     /**
   505      * Are corresponding elements of ts subtypes of ss, allowing
   506      * unchecked conversions?  If lists are of different length,
   507      * return false.
   508      **/
   509     public boolean isSubtypesUnchecked(List<Type> ts, List<Type> ss, Warner warn) {
   510         while (ts.tail != null && ss.tail != null
   511                /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
   512                isSubtypeUnchecked(ts.head, ss.head, warn)) {
   513             ts = ts.tail;
   514             ss = ss.tail;
   515         }
   516         return ts.tail == null && ss.tail == null;
   517         /*inlined: ts.isEmpty() && ss.isEmpty();*/
   518     }
   519     // </editor-fold>
   521     // <editor-fold defaultstate="collapsed" desc="isSuperType">
   522     /**
   523      * Is t a supertype of s?
   524      */
   525     public boolean isSuperType(Type t, Type s) {
   526         switch (t.tag) {
   527         case ERROR:
   528             return true;
   529         case UNDETVAR: {
   530             UndetVar undet = (UndetVar)t;
   531             if (t == s ||
   532                 undet.qtype == s ||
   533                 s.tag == ERROR ||
   534                 s.tag == BOT) return true;
   535             if (undet.inst != null)
   536                 return isSubtype(s, undet.inst);
   537             undet.lobounds = undet.lobounds.prepend(s);
   538             return true;
   539         }
   540         default:
   541             return isSubtype(s, t);
   542         }
   543     }
   544     // </editor-fold>
   546     // <editor-fold defaultstate="collapsed" desc="isSameType">
   547     /**
   548      * Are corresponding elements of the lists the same type?  If
   549      * lists are of different length, return false.
   550      */
   551     public boolean isSameTypes(List<Type> ts, List<Type> ss) {
   552         while (ts.tail != null && ss.tail != null
   553                /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
   554                isSameType(ts.head, ss.head)) {
   555             ts = ts.tail;
   556             ss = ss.tail;
   557         }
   558         return ts.tail == null && ss.tail == null;
   559         /*inlined: ts.isEmpty() && ss.isEmpty();*/
   560     }
   562     /**
   563      * Is t the same type as s?
   564      */
   565     public boolean isSameType(Type t, Type s) {
   566         return isSameType.visit(t, s);
   567     }
   568     // where
   569         private TypeRelation isSameType = new TypeRelation() {
   571             public Boolean visitType(Type t, Type s) {
   572                 if (t == s)
   573                     return true;
   575                 if (s.tag >= firstPartialTag)
   576                     return visit(s, t);
   578                 switch (t.tag) {
   579                 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
   580                 case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE:
   581                     return t.tag == s.tag;
   582                 case TYPEVAR:
   583                     return s.isSuperBound()
   584                         && !s.isExtendsBound()
   585                         && visit(t, upperBound(s));
   586                 default:
   587                     throw new AssertionError("isSameType " + t.tag);
   588                 }
   589             }
   591             @Override
   592             public Boolean visitWildcardType(WildcardType t, Type s) {
   593                 if (s.tag >= firstPartialTag)
   594                     return visit(s, t);
   595                 else
   596                     return false;
   597             }
   599             @Override
   600             public Boolean visitClassType(ClassType t, Type s) {
   601                 if (t == s)
   602                     return true;
   604                 if (s.tag >= firstPartialTag)
   605                     return visit(s, t);
   607                 if (s.isSuperBound() && !s.isExtendsBound())
   608                     return visit(t, upperBound(s)) && visit(t, lowerBound(s));
   610                 if (t.isCompound() && s.isCompound()) {
   611                     if (!visit(supertype(t), supertype(s)))
   612                         return false;
   614                     HashSet<SingletonType> set = new HashSet<SingletonType>();
   615                     for (Type x : interfaces(t))
   616                         set.add(new SingletonType(x));
   617                     for (Type x : interfaces(s)) {
   618                         if (!set.remove(new SingletonType(x)))
   619                             return false;
   620                     }
   621                     return (set.size() == 0);
   622                 }
   623                 return t.tsym == s.tsym
   624                     && visit(t.getEnclosingType(), s.getEnclosingType())
   625                     && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments());
   626             }
   628             @Override
   629             public Boolean visitArrayType(ArrayType t, Type s) {
   630                 if (t == s)
   631                     return true;
   633                 if (s.tag >= firstPartialTag)
   634                     return visit(s, t);
   636                 return s.tag == ARRAY
   637                     && containsTypeEquivalent(t.elemtype, elemtype(s));
   638             }
   640             @Override
   641             public Boolean visitMethodType(MethodType t, Type s) {
   642                 // isSameType for methods does not take thrown
   643                 // exceptions into account!
   644                 return hasSameArgs(t, s) && visit(t.getReturnType(), s.getReturnType());
   645             }
   647             @Override
   648             public Boolean visitPackageType(PackageType t, Type s) {
   649                 return t == s;
   650             }
   652             @Override
   653             public Boolean visitForAll(ForAll t, Type s) {
   654                 if (s.tag != FORALL)
   655                     return false;
   657                 ForAll forAll = (ForAll)s;
   658                 return hasSameBounds(t, forAll)
   659                     && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
   660             }
   662             @Override
   663             public Boolean visitUndetVar(UndetVar t, Type s) {
   664                 if (s.tag == WILDCARD)
   665                     // FIXME, this might be leftovers from before capture conversion
   666                     return false;
   668                 if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN)
   669                     return true;
   671                 if (t.inst != null)
   672                     return visit(t.inst, s);
   674                 t.inst = fromUnknownFun.apply(s);
   675                 for (List<Type> l = t.lobounds; l.nonEmpty(); l = l.tail) {
   676                     if (!isSubtype(l.head, t.inst))
   677                         return false;
   678                 }
   679                 for (List<Type> l = t.hibounds; l.nonEmpty(); l = l.tail) {
   680                     if (!isSubtype(t.inst, l.head))
   681                         return false;
   682                 }
   683                 return true;
   684             }
   686             @Override
   687             public Boolean visitErrorType(ErrorType t, Type s) {
   688                 return true;
   689             }
   690         };
   691     // </editor-fold>
   693     // <editor-fold defaultstate="collapsed" desc="fromUnknownFun">
   694     /**
   695      * A mapping that turns all unknown types in this type to fresh
   696      * unknown variables.
   697      */
   698     public Mapping fromUnknownFun = new Mapping("fromUnknownFun") {
   699             public Type apply(Type t) {
   700                 if (t.tag == UNKNOWN) return new UndetVar(t);
   701                 else return t.map(this);
   702             }
   703         };
   704     // </editor-fold>
   706     // <editor-fold defaultstate="collapsed" desc="Contains Type">
   707     public boolean containedBy(Type t, Type s) {
   708         switch (t.tag) {
   709         case UNDETVAR:
   710             if (s.tag == WILDCARD) {
   711                 UndetVar undetvar = (UndetVar)t;
   713                 // Because of wildcard capture, s must be on the left
   714                 // hand side of an assignment.  Furthermore, t is an
   715                 // underconstrained type variable, for example, one
   716                 // that is only used in the return type of a method.
   717                 // If the type variable is truly underconstrained, it
   718                 // cannot have any low bounds:
   719                 assert undetvar.lobounds.isEmpty() : undetvar;
   721                 undetvar.inst = glb(upperBound(s), undetvar.inst);
   722                 return true;
   723             } else {
   724                 return isSameType(t, s);
   725             }
   726         case ERROR:
   727             return true;
   728         default:
   729             return containsType(s, t);
   730         }
   731     }
   733     boolean containsType(List<Type> ts, List<Type> ss) {
   734         while (ts.nonEmpty() && ss.nonEmpty()
   735                && containsType(ts.head, ss.head)) {
   736             ts = ts.tail;
   737             ss = ss.tail;
   738         }
   739         return ts.isEmpty() && ss.isEmpty();
   740     }
   742     /**
   743      * Check if t contains s.
   744      *
   745      * <p>T contains S if:
   746      *
   747      * <p>{@code L(T) <: L(S) && U(S) <: U(T)}
   748      *
   749      * <p>This relation is only used by ClassType.isSubtype(), that
   750      * is,
   751      *
   752      * <p>{@code C<S> <: C<T> if T contains S.}
   753      *
   754      * <p>Because of F-bounds, this relation can lead to infinite
   755      * recursion.  Thus we must somehow break that recursion.  Notice
   756      * that containsType() is only called from ClassType.isSubtype().
   757      * Since the arguments have already been checked against their
   758      * bounds, we know:
   759      *
   760      * <p>{@code U(S) <: U(T) if T is "super" bound (U(T) *is* the bound)}
   761      *
   762      * <p>{@code L(T) <: L(S) if T is "extends" bound (L(T) is bottom)}
   763      *
   764      * @param t a type
   765      * @param s a type
   766      */
   767     public boolean containsType(Type t, Type s) {
   768         return containsType.visit(t, s);
   769     }
   770     // where
   771         private TypeRelation containsType = new TypeRelation() {
   773             private Type U(Type t) {
   774                 while (t.tag == WILDCARD) {
   775                     WildcardType w = (WildcardType)t;
   776                     if (w.isSuperBound())
   777                         return w.bound == null ? syms.objectType : w.bound.bound;
   778                     else
   779                         t = w.type;
   780                 }
   781                 return t;
   782             }
   784             private Type L(Type t) {
   785                 while (t.tag == WILDCARD) {
   786                     WildcardType w = (WildcardType)t;
   787                     if (w.isExtendsBound())
   788                         return syms.botType;
   789                     else
   790                         t = w.type;
   791                 }
   792                 return t;
   793             }
   795             public Boolean visitType(Type t, Type s) {
   796                 if (s.tag >= firstPartialTag)
   797                     return containedBy(s, t);
   798                 else
   799                     return isSameType(t, s);
   800             }
   802             void debugContainsType(WildcardType t, Type s) {
   803                 System.err.println();
   804                 System.err.format(" does %s contain %s?%n", t, s);
   805                 System.err.format(" %s U(%s) <: U(%s) %s = %s%n",
   806                                   upperBound(s), s, t, U(t),
   807                                   t.isSuperBound()
   808                                   || isSubtypeNoCapture(upperBound(s), U(t)));
   809                 System.err.format(" %s L(%s) <: L(%s) %s = %s%n",
   810                                   L(t), t, s, lowerBound(s),
   811                                   t.isExtendsBound()
   812                                   || isSubtypeNoCapture(L(t), lowerBound(s)));
   813                 System.err.println();
   814             }
   816             @Override
   817             public Boolean visitWildcardType(WildcardType t, Type s) {
   818                 if (s.tag >= firstPartialTag)
   819                     return containedBy(s, t);
   820                 else {
   821                     // debugContainsType(t, s);
   822                     return isSameWildcard(t, s)
   823                         || isCaptureOf(s, t)
   824                         || ((t.isExtendsBound() || isSubtypeNoCapture(L(t), lowerBound(s))) &&
   825                             (t.isSuperBound() || isSubtypeNoCapture(upperBound(s), U(t))));
   826                 }
   827             }
   829             @Override
   830             public Boolean visitUndetVar(UndetVar t, Type s) {
   831                 if (s.tag != WILDCARD)
   832                     return isSameType(t, s);
   833                 else
   834                     return false;
   835             }
   837             @Override
   838             public Boolean visitErrorType(ErrorType t, Type s) {
   839                 return true;
   840             }
   841         };
   843     public boolean isCaptureOf(Type s, WildcardType t) {
   844         if (s.tag != TYPEVAR || !((TypeVar)s).isCaptured())
   845             return false;
   846         return isSameWildcard(t, ((CapturedType)s).wildcard);
   847     }
   849     public boolean isSameWildcard(WildcardType t, Type s) {
   850         if (s.tag != WILDCARD)
   851             return false;
   852         WildcardType w = (WildcardType)s;
   853         return w.kind == t.kind && w.type == t.type;
   854     }
   856     public boolean containsTypeEquivalent(List<Type> ts, List<Type> ss) {
   857         while (ts.nonEmpty() && ss.nonEmpty()
   858                && containsTypeEquivalent(ts.head, ss.head)) {
   859             ts = ts.tail;
   860             ss = ss.tail;
   861         }
   862         return ts.isEmpty() && ss.isEmpty();
   863     }
   864     // </editor-fold>
   866     // <editor-fold defaultstate="collapsed" desc="isCastable">
   867     public boolean isCastable(Type t, Type s) {
   868         return isCastable(t, s, Warner.noWarnings);
   869     }
   871     /**
   872      * Is t is castable to s?<br>
   873      * s is assumed to be an erased type.<br>
   874      * (not defined for Method and ForAll types).
   875      */
   876     public boolean isCastable(Type t, Type s, Warner warn) {
   877         if (t == s)
   878             return true;
   880         if (t.isPrimitive() != s.isPrimitive())
   881             return allowBoxing && isConvertible(t, s, warn);
   883         if (warn != warnStack.head) {
   884             try {
   885                 warnStack = warnStack.prepend(warn);
   886                 return isCastable.visit(t, s);
   887             } finally {
   888                 warnStack = warnStack.tail;
   889             }
   890         } else {
   891             return isCastable.visit(t, s);
   892         }
   893     }
   894     // where
   895         private TypeRelation isCastable = new TypeRelation() {
   897             public Boolean visitType(Type t, Type s) {
   898                 if (s.tag == ERROR)
   899                     return true;
   901                 switch (t.tag) {
   902                 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
   903                 case DOUBLE:
   904                     return s.tag <= DOUBLE;
   905                 case BOOLEAN:
   906                     return s.tag == BOOLEAN;
   907                 case VOID:
   908                     return false;
   909                 case BOT:
   910                     return isSubtype(t, s);
   911                 default:
   912                     throw new AssertionError();
   913                 }
   914             }
   916             @Override
   917             public Boolean visitWildcardType(WildcardType t, Type s) {
   918                 return isCastable(upperBound(t), s, warnStack.head);
   919             }
   921             @Override
   922             public Boolean visitClassType(ClassType t, Type s) {
   923                 if (s.tag == ERROR || s.tag == BOT)
   924                     return true;
   926                 if (s.tag == TYPEVAR) {
   927                     if (isCastable(s.getUpperBound(), t, Warner.noWarnings)) {
   928                         warnStack.head.warnUnchecked();
   929                         return true;
   930                     } else {
   931                         return false;
   932                     }
   933                 }
   935                 if (t.isCompound()) {
   936                     if (!visit(supertype(t), s))
   937                         return false;
   938                     for (Type intf : interfaces(t)) {
   939                         if (!visit(intf, s))
   940                             return false;
   941                     }
   942                     return true;
   943                 }
   945                 if (s.isCompound()) {
   946                     // call recursively to reuse the above code
   947                     return visitClassType((ClassType)s, t);
   948                 }
   950                 if (s.tag == CLASS || s.tag == ARRAY) {
   951                     boolean upcast;
   952                     if ((upcast = isSubtype(erasure(t), erasure(s)))
   953                         || isSubtype(erasure(s), erasure(t))) {
   954                         if (!upcast && s.tag == ARRAY) {
   955                             if (!isReifiable(s))
   956                                 warnStack.head.warnUnchecked();
   957                             return true;
   958                         } else if (s.isRaw()) {
   959                             return true;
   960                         } else if (t.isRaw()) {
   961                             if (!isUnbounded(s))
   962                                 warnStack.head.warnUnchecked();
   963                             return true;
   964                         }
   965                         // Assume |a| <: |b|
   966                         final Type a = upcast ? t : s;
   967                         final Type b = upcast ? s : t;
   968                         final boolean HIGH = true;
   969                         final boolean LOW = false;
   970                         final boolean DONT_REWRITE_TYPEVARS = false;
   971                         Type aHigh = rewriteQuantifiers(a, HIGH, DONT_REWRITE_TYPEVARS);
   972                         Type aLow  = rewriteQuantifiers(a, LOW,  DONT_REWRITE_TYPEVARS);
   973                         Type bHigh = rewriteQuantifiers(b, HIGH, DONT_REWRITE_TYPEVARS);
   974                         Type bLow  = rewriteQuantifiers(b, LOW,  DONT_REWRITE_TYPEVARS);
   975                         Type lowSub = asSub(bLow, aLow.tsym);
   976                         Type highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym);
   977                         if (highSub == null) {
   978                             final boolean REWRITE_TYPEVARS = true;
   979                             aHigh = rewriteQuantifiers(a, HIGH, REWRITE_TYPEVARS);
   980                             aLow  = rewriteQuantifiers(a, LOW,  REWRITE_TYPEVARS);
   981                             bHigh = rewriteQuantifiers(b, HIGH, REWRITE_TYPEVARS);
   982                             bLow  = rewriteQuantifiers(b, LOW,  REWRITE_TYPEVARS);
   983                             lowSub = asSub(bLow, aLow.tsym);
   984                             highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym);
   985                         }
   986                         if (highSub != null) {
   987                             assert a.tsym == highSub.tsym && a.tsym == lowSub.tsym
   988                                 : a.tsym + " != " + highSub.tsym + " != " + lowSub.tsym;
   989                             if (!disjointTypes(aHigh.getTypeArguments(), highSub.getTypeArguments())
   990                                 && !disjointTypes(aHigh.getTypeArguments(), lowSub.getTypeArguments())
   991                                 && !disjointTypes(aLow.getTypeArguments(), highSub.getTypeArguments())
   992                                 && !disjointTypes(aLow.getTypeArguments(), lowSub.getTypeArguments())) {
   993                                 if (upcast ? giveWarning(a, highSub) || giveWarning(a, lowSub)
   994                                            : giveWarning(highSub, a) || giveWarning(lowSub, a))
   995                                     warnStack.head.warnUnchecked();
   996                                 return true;
   997                             }
   998                         }
   999                         if (isReifiable(s))
  1000                             return isSubtypeUnchecked(a, b);
  1001                         else
  1002                             return isSubtypeUnchecked(a, b, warnStack.head);
  1005                     // Sidecast
  1006                     if (s.tag == CLASS) {
  1007                         if ((s.tsym.flags() & INTERFACE) != 0) {
  1008                             return ((t.tsym.flags() & FINAL) == 0)
  1009                                 ? sideCast(t, s, warnStack.head)
  1010                                 : sideCastFinal(t, s, warnStack.head);
  1011                         } else if ((t.tsym.flags() & INTERFACE) != 0) {
  1012                             return ((s.tsym.flags() & FINAL) == 0)
  1013                                 ? sideCast(t, s, warnStack.head)
  1014                                 : sideCastFinal(t, s, warnStack.head);
  1015                         } else {
  1016                             // unrelated class types
  1017                             return false;
  1021                 return false;
  1024             @Override
  1025             public Boolean visitArrayType(ArrayType t, Type s) {
  1026                 switch (s.tag) {
  1027                 case ERROR:
  1028                 case BOT:
  1029                     return true;
  1030                 case TYPEVAR:
  1031                     if (isCastable(s, t, Warner.noWarnings)) {
  1032                         warnStack.head.warnUnchecked();
  1033                         return true;
  1034                     } else {
  1035                         return false;
  1037                 case CLASS:
  1038                     return isSubtype(t, s);
  1039                 case ARRAY:
  1040                     if (elemtype(t).tag <= lastBaseTag) {
  1041                         return elemtype(t).tag == elemtype(s).tag;
  1042                     } else {
  1043                         return visit(elemtype(t), elemtype(s));
  1045                 default:
  1046                     return false;
  1050             @Override
  1051             public Boolean visitTypeVar(TypeVar t, Type s) {
  1052                 switch (s.tag) {
  1053                 case ERROR:
  1054                 case BOT:
  1055                     return true;
  1056                 case TYPEVAR:
  1057                     if (isSubtype(t, s)) {
  1058                         return true;
  1059                     } else if (isCastable(t.bound, s, Warner.noWarnings)) {
  1060                         warnStack.head.warnUnchecked();
  1061                         return true;
  1062                     } else {
  1063                         return false;
  1065                 default:
  1066                     return isCastable(t.bound, s, warnStack.head);
  1070             @Override
  1071             public Boolean visitErrorType(ErrorType t, Type s) {
  1072                 return true;
  1074         };
  1075     // </editor-fold>
  1077     // <editor-fold defaultstate="collapsed" desc="disjointTypes">
  1078     public boolean disjointTypes(List<Type> ts, List<Type> ss) {
  1079         while (ts.tail != null && ss.tail != null) {
  1080             if (disjointType(ts.head, ss.head)) return true;
  1081             ts = ts.tail;
  1082             ss = ss.tail;
  1084         return false;
  1087     /**
  1088      * Two types or wildcards are considered disjoint if it can be
  1089      * proven that no type can be contained in both. It is
  1090      * conservative in that it is allowed to say that two types are
  1091      * not disjoint, even though they actually are.
  1093      * The type C<X> is castable to C<Y> exactly if X and Y are not
  1094      * disjoint.
  1095      */
  1096     public boolean disjointType(Type t, Type s) {
  1097         return disjointType.visit(t, s);
  1099     // where
  1100         private TypeRelation disjointType = new TypeRelation() {
  1102             private Set<TypePair> cache = new HashSet<TypePair>();
  1104             public Boolean visitType(Type t, Type s) {
  1105                 if (s.tag == WILDCARD)
  1106                     return visit(s, t);
  1107                 else
  1108                     return notSoftSubtypeRecursive(t, s) || notSoftSubtypeRecursive(s, t);
  1111             private boolean isCastableRecursive(Type t, Type s) {
  1112                 TypePair pair = new TypePair(t, s);
  1113                 if (cache.add(pair)) {
  1114                     try {
  1115                         return Types.this.isCastable(t, s);
  1116                     } finally {
  1117                         cache.remove(pair);
  1119                 } else {
  1120                     return true;
  1124             private boolean notSoftSubtypeRecursive(Type t, Type s) {
  1125                 TypePair pair = new TypePair(t, s);
  1126                 if (cache.add(pair)) {
  1127                     try {
  1128                         return Types.this.notSoftSubtype(t, s);
  1129                     } finally {
  1130                         cache.remove(pair);
  1132                 } else {
  1133                     return false;
  1137             @Override
  1138             public Boolean visitWildcardType(WildcardType t, Type s) {
  1139                 if (t.isUnbound())
  1140                     return false;
  1142                 if (s.tag != WILDCARD) {
  1143                     if (t.isExtendsBound())
  1144                         return notSoftSubtypeRecursive(s, t.type);
  1145                     else // isSuperBound()
  1146                         return notSoftSubtypeRecursive(t.type, s);
  1149                 if (s.isUnbound())
  1150                     return false;
  1152                 if (t.isExtendsBound()) {
  1153                     if (s.isExtendsBound())
  1154                         return !isCastableRecursive(t.type, upperBound(s));
  1155                     else if (s.isSuperBound())
  1156                         return notSoftSubtypeRecursive(lowerBound(s), t.type);
  1157                 } else if (t.isSuperBound()) {
  1158                     if (s.isExtendsBound())
  1159                         return notSoftSubtypeRecursive(t.type, upperBound(s));
  1161                 return false;
  1163         };
  1164     // </editor-fold>
  1166     // <editor-fold defaultstate="collapsed" desc="lowerBoundArgtypes">
  1167     /**
  1168      * Returns the lower bounds of the formals of a method.
  1169      */
  1170     public List<Type> lowerBoundArgtypes(Type t) {
  1171         return map(t.getParameterTypes(), lowerBoundMapping);
  1173     private final Mapping lowerBoundMapping = new Mapping("lowerBound") {
  1174             public Type apply(Type t) {
  1175                 return lowerBound(t);
  1177         };
  1178     // </editor-fold>
  1180     // <editor-fold defaultstate="collapsed" desc="notSoftSubtype">
  1181     /**
  1182      * This relation answers the question: is impossible that
  1183      * something of type `t' can be a subtype of `s'? This is
  1184      * different from the question "is `t' not a subtype of `s'?"
  1185      * when type variables are involved: Integer is not a subtype of T
  1186      * where <T extends Number> but it is not true that Integer cannot
  1187      * possibly be a subtype of T.
  1188      */
  1189     public boolean notSoftSubtype(Type t, Type s) {
  1190         if (t == s) return false;
  1191         if (t.tag == TYPEVAR) {
  1192             TypeVar tv = (TypeVar) t;
  1193             if (s.tag == TYPEVAR)
  1194                 s = s.getUpperBound();
  1195             return !isCastable(tv.bound,
  1196                                s,
  1197                                Warner.noWarnings);
  1199         if (s.tag != WILDCARD)
  1200             s = upperBound(s);
  1201         if (s.tag == TYPEVAR)
  1202             s = s.getUpperBound();
  1203         return !isSubtype(t, s);
  1205     // </editor-fold>
  1207     // <editor-fold defaultstate="collapsed" desc="isReifiable">
  1208     public boolean isReifiable(Type t) {
  1209         return isReifiable.visit(t);
  1211     // where
  1212         private UnaryVisitor<Boolean> isReifiable = new UnaryVisitor<Boolean>() {
  1214             public Boolean visitType(Type t, Void ignored) {
  1215                 return true;
  1218             @Override
  1219             public Boolean visitClassType(ClassType t, Void ignored) {
  1220                 if (!t.isParameterized())
  1221                     return true;
  1223                 for (Type param : t.allparams()) {
  1224                     if (!param.isUnbound())
  1225                         return false;
  1227                 return true;
  1230             @Override
  1231             public Boolean visitArrayType(ArrayType t, Void ignored) {
  1232                 return visit(t.elemtype);
  1235             @Override
  1236             public Boolean visitTypeVar(TypeVar t, Void ignored) {
  1237                 return false;
  1239         };
  1240     // </editor-fold>
  1242     // <editor-fold defaultstate="collapsed" desc="Array Utils">
  1243     public boolean isArray(Type t) {
  1244         while (t.tag == WILDCARD)
  1245             t = upperBound(t);
  1246         return t.tag == ARRAY;
  1249     /**
  1250      * The element type of an array.
  1251      */
  1252     public Type elemtype(Type t) {
  1253         switch (t.tag) {
  1254         case WILDCARD:
  1255             return elemtype(upperBound(t));
  1256         case ARRAY:
  1257             return ((ArrayType)t).elemtype;
  1258         case FORALL:
  1259             return elemtype(((ForAll)t).qtype);
  1260         case ERROR:
  1261             return t;
  1262         default:
  1263             return null;
  1267     /**
  1268      * Mapping to take element type of an arraytype
  1269      */
  1270     private Mapping elemTypeFun = new Mapping ("elemTypeFun") {
  1271         public Type apply(Type t) { return elemtype(t); }
  1272     };
  1274     /**
  1275      * The number of dimensions of an array type.
  1276      */
  1277     public int dimensions(Type t) {
  1278         int result = 0;
  1279         while (t.tag == ARRAY) {
  1280             result++;
  1281             t = elemtype(t);
  1283         return result;
  1285     // </editor-fold>
  1287     // <editor-fold defaultstate="collapsed" desc="asSuper">
  1288     /**
  1289      * Return the (most specific) base type of t that starts with the
  1290      * given symbol.  If none exists, return null.
  1292      * @param t a type
  1293      * @param sym a symbol
  1294      */
  1295     public Type asSuper(Type t, Symbol sym) {
  1296         return asSuper.visit(t, sym);
  1298     // where
  1299         private SimpleVisitor<Type,Symbol> asSuper = new SimpleVisitor<Type,Symbol>() {
  1301             public Type visitType(Type t, Symbol sym) {
  1302                 return null;
  1305             @Override
  1306             public Type visitClassType(ClassType t, Symbol sym) {
  1307                 if (t.tsym == sym)
  1308                     return t;
  1310                 Type st = supertype(t);
  1311                 if (st.tag == CLASS || st.tag == TYPEVAR || st.tag == ERROR) {
  1312                     Type x = asSuper(st, sym);
  1313                     if (x != null)
  1314                         return x;
  1316                 if ((sym.flags() & INTERFACE) != 0) {
  1317                     for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
  1318                         Type x = asSuper(l.head, sym);
  1319                         if (x != null)
  1320                             return x;
  1323                 return null;
  1326             @Override
  1327             public Type visitArrayType(ArrayType t, Symbol sym) {
  1328                 return isSubtype(t, sym.type) ? sym.type : null;
  1331             @Override
  1332             public Type visitTypeVar(TypeVar t, Symbol sym) {
  1333                 if (t.tsym == sym)
  1334                     return t;
  1335                 else
  1336                     return asSuper(t.bound, sym);
  1339             @Override
  1340             public Type visitErrorType(ErrorType t, Symbol sym) {
  1341                 return t;
  1343         };
  1345     /**
  1346      * Return the base type of t or any of its outer types that starts
  1347      * with the given symbol.  If none exists, return null.
  1349      * @param t a type
  1350      * @param sym a symbol
  1351      */
  1352     public Type asOuterSuper(Type t, Symbol sym) {
  1353         switch (t.tag) {
  1354         case CLASS:
  1355             do {
  1356                 Type s = asSuper(t, sym);
  1357                 if (s != null) return s;
  1358                 t = t.getEnclosingType();
  1359             } while (t.tag == CLASS);
  1360             return null;
  1361         case ARRAY:
  1362             return isSubtype(t, sym.type) ? sym.type : null;
  1363         case TYPEVAR:
  1364             return asSuper(t, sym);
  1365         case ERROR:
  1366             return t;
  1367         default:
  1368             return null;
  1372     /**
  1373      * Return the base type of t or any of its enclosing types that
  1374      * starts with the given symbol.  If none exists, return null.
  1376      * @param t a type
  1377      * @param sym a symbol
  1378      */
  1379     public Type asEnclosingSuper(Type t, Symbol sym) {
  1380         switch (t.tag) {
  1381         case CLASS:
  1382             do {
  1383                 Type s = asSuper(t, sym);
  1384                 if (s != null) return s;
  1385                 Type outer = t.getEnclosingType();
  1386                 t = (outer.tag == CLASS) ? outer :
  1387                     (t.tsym.owner.enclClass() != null) ? t.tsym.owner.enclClass().type :
  1388                     Type.noType;
  1389             } while (t.tag == CLASS);
  1390             return null;
  1391         case ARRAY:
  1392             return isSubtype(t, sym.type) ? sym.type : null;
  1393         case TYPEVAR:
  1394             return asSuper(t, sym);
  1395         case ERROR:
  1396             return t;
  1397         default:
  1398             return null;
  1401     // </editor-fold>
  1403     // <editor-fold defaultstate="collapsed" desc="memberType">
  1404     /**
  1405      * The type of given symbol, seen as a member of t.
  1407      * @param t a type
  1408      * @param sym a symbol
  1409      */
  1410     public Type memberType(Type t, Symbol sym) {
  1411         return (sym.flags() & STATIC) != 0
  1412             ? sym.type
  1413             : memberType.visit(t, sym);
  1415     // where
  1416         private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
  1418             public Type visitType(Type t, Symbol sym) {
  1419                 return sym.type;
  1422             @Override
  1423             public Type visitWildcardType(WildcardType t, Symbol sym) {
  1424                 return memberType(upperBound(t), sym);
  1427             @Override
  1428             public Type visitClassType(ClassType t, Symbol sym) {
  1429                 Symbol owner = sym.owner;
  1430                 long flags = sym.flags();
  1431                 if (((flags & STATIC) == 0) && owner.type.isParameterized()) {
  1432                     Type base = asOuterSuper(t, owner);
  1433                     //if t is an intersection type T = CT & I1 & I2 ... & In
  1434                     //its supertypes CT, I1, ... In might contain wildcards
  1435                     //so we need to go through capture conversion
  1436                     base = t.isCompound() ? capture(base) : base;
  1437                     if (base != null) {
  1438                         List<Type> ownerParams = owner.type.allparams();
  1439                         List<Type> baseParams = base.allparams();
  1440                         if (ownerParams.nonEmpty()) {
  1441                             if (baseParams.isEmpty()) {
  1442                                 // then base is a raw type
  1443                                 return erasure(sym.type);
  1444                             } else {
  1445                                 return subst(sym.type, ownerParams, baseParams);
  1450                 return sym.type;
  1453             @Override
  1454             public Type visitTypeVar(TypeVar t, Symbol sym) {
  1455                 return memberType(t.bound, sym);
  1458             @Override
  1459             public Type visitErrorType(ErrorType t, Symbol sym) {
  1460                 return t;
  1462         };
  1463     // </editor-fold>
  1465     // <editor-fold defaultstate="collapsed" desc="isAssignable">
  1466     public boolean isAssignable(Type t, Type s) {
  1467         return isAssignable(t, s, Warner.noWarnings);
  1470     /**
  1471      * Is t assignable to s?<br>
  1472      * Equivalent to subtype except for constant values and raw
  1473      * types.<br>
  1474      * (not defined for Method and ForAll types)
  1475      */
  1476     public boolean isAssignable(Type t, Type s, Warner warn) {
  1477         if (t.tag == ERROR)
  1478             return true;
  1479         if (t.tag <= INT && t.constValue() != null) {
  1480             int value = ((Number)t.constValue()).intValue();
  1481             switch (s.tag) {
  1482             case BYTE:
  1483                 if (Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE)
  1484                     return true;
  1485                 break;
  1486             case CHAR:
  1487                 if (Character.MIN_VALUE <= value && value <= Character.MAX_VALUE)
  1488                     return true;
  1489                 break;
  1490             case SHORT:
  1491                 if (Short.MIN_VALUE <= value && value <= Short.MAX_VALUE)
  1492                     return true;
  1493                 break;
  1494             case INT:
  1495                 return true;
  1496             case CLASS:
  1497                 switch (unboxedType(s).tag) {
  1498                 case BYTE:
  1499                 case CHAR:
  1500                 case SHORT:
  1501                     return isAssignable(t, unboxedType(s), warn);
  1503                 break;
  1506         return isConvertible(t, s, warn);
  1508     // </editor-fold>
  1510     // <editor-fold defaultstate="collapsed" desc="erasure">
  1511     /**
  1512      * The erasure of t {@code |t|} -- the type that results when all
  1513      * type parameters in t are deleted.
  1514      */
  1515     public Type erasure(Type t) {
  1516         return erasure(t, false);
  1518     //where
  1519     private Type erasure(Type t, boolean recurse) {
  1520         if (t.tag <= lastBaseTag)
  1521             return t; /* fast special case */
  1522         else
  1523             return erasure.visit(t, recurse);
  1525     // where
  1526         private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() {
  1527             public Type visitType(Type t, Boolean recurse) {
  1528                 if (t.tag <= lastBaseTag)
  1529                     return t; /*fast special case*/
  1530                 else
  1531                     return t.map(recurse ? erasureRecFun : erasureFun);
  1534             @Override
  1535             public Type visitWildcardType(WildcardType t, Boolean recurse) {
  1536                 return erasure(upperBound(t), recurse);
  1539             @Override
  1540             public Type visitClassType(ClassType t, Boolean recurse) {
  1541                 Type erased = t.tsym.erasure(Types.this);
  1542                 if (recurse) {
  1543                     erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym);
  1545                 return erased;
  1548             @Override
  1549             public Type visitTypeVar(TypeVar t, Boolean recurse) {
  1550                 return erasure(t.bound, recurse);
  1553             @Override
  1554             public Type visitErrorType(ErrorType t, Boolean recurse) {
  1555                 return t;
  1557         };
  1559     private Mapping erasureFun = new Mapping ("erasure") {
  1560             public Type apply(Type t) { return erasure(t); }
  1561         };
  1563     private Mapping erasureRecFun = new Mapping ("erasureRecursive") {
  1564         public Type apply(Type t) { return erasureRecursive(t); }
  1565     };
  1567     public List<Type> erasure(List<Type> ts) {
  1568         return Type.map(ts, erasureFun);
  1571     public Type erasureRecursive(Type t) {
  1572         return erasure(t, true);
  1575     public List<Type> erasureRecursive(List<Type> ts) {
  1576         return Type.map(ts, erasureRecFun);
  1578     // </editor-fold>
  1580     // <editor-fold defaultstate="collapsed" desc="makeCompoundType">
  1581     /**
  1582      * Make a compound type from non-empty list of types
  1584      * @param bounds            the types from which the compound type is formed
  1585      * @param supertype         is objectType if all bounds are interfaces,
  1586      *                          null otherwise.
  1587      */
  1588     public Type makeCompoundType(List<Type> bounds,
  1589                                  Type supertype) {
  1590         ClassSymbol bc =
  1591             new ClassSymbol(ABSTRACT|PUBLIC|SYNTHETIC|COMPOUND|ACYCLIC,
  1592                             Type.moreInfo
  1593                                 ? names.fromString(bounds.toString())
  1594                                 : names.empty,
  1595                             syms.noSymbol);
  1596         if (bounds.head.tag == TYPEVAR)
  1597             // error condition, recover
  1598                 bc.erasure_field = syms.objectType;
  1599             else
  1600                 bc.erasure_field = erasure(bounds.head);
  1601             bc.members_field = new Scope(bc);
  1602         ClassType bt = (ClassType)bc.type;
  1603         bt.allparams_field = List.nil();
  1604         if (supertype != null) {
  1605             bt.supertype_field = supertype;
  1606             bt.interfaces_field = bounds;
  1607         } else {
  1608             bt.supertype_field = bounds.head;
  1609             bt.interfaces_field = bounds.tail;
  1611         assert bt.supertype_field.tsym.completer != null
  1612             || !bt.supertype_field.isInterface()
  1613             : bt.supertype_field;
  1614         return bt;
  1617     /**
  1618      * Same as {@link #makeCompoundType(List,Type)}, except that the
  1619      * second parameter is computed directly. Note that this might
  1620      * cause a symbol completion.  Hence, this version of
  1621      * makeCompoundType may not be called during a classfile read.
  1622      */
  1623     public Type makeCompoundType(List<Type> bounds) {
  1624         Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ?
  1625             supertype(bounds.head) : null;
  1626         return makeCompoundType(bounds, supertype);
  1629     /**
  1630      * A convenience wrapper for {@link #makeCompoundType(List)}; the
  1631      * arguments are converted to a list and passed to the other
  1632      * method.  Note that this might cause a symbol completion.
  1633      * Hence, this version of makeCompoundType may not be called
  1634      * during a classfile read.
  1635      */
  1636     public Type makeCompoundType(Type bound1, Type bound2) {
  1637         return makeCompoundType(List.of(bound1, bound2));
  1639     // </editor-fold>
  1641     // <editor-fold defaultstate="collapsed" desc="supertype">
  1642     public Type supertype(Type t) {
  1643         return supertype.visit(t);
  1645     // where
  1646         private UnaryVisitor<Type> supertype = new UnaryVisitor<Type>() {
  1648             public Type visitType(Type t, Void ignored) {
  1649                 // A note on wildcards: there is no good way to
  1650                 // determine a supertype for a super bounded wildcard.
  1651                 return null;
  1654             @Override
  1655             public Type visitClassType(ClassType t, Void ignored) {
  1656                 if (t.supertype_field == null) {
  1657                     Type supertype = ((ClassSymbol)t.tsym).getSuperclass();
  1658                     // An interface has no superclass; its supertype is Object.
  1659                     if (t.isInterface())
  1660                         supertype = ((ClassType)t.tsym.type).supertype_field;
  1661                     if (t.supertype_field == null) {
  1662                         List<Type> actuals = classBound(t).allparams();
  1663                         List<Type> formals = t.tsym.type.allparams();
  1664                         if (t.hasErasedSupertypes()) {
  1665                             t.supertype_field = erasureRecursive(supertype);
  1666                         } else if (formals.nonEmpty()) {
  1667                             t.supertype_field = subst(supertype, formals, actuals);
  1669                         else {
  1670                             t.supertype_field = supertype;
  1674                 return t.supertype_field;
  1677             /**
  1678              * The supertype is always a class type. If the type
  1679              * variable's bounds start with a class type, this is also
  1680              * the supertype.  Otherwise, the supertype is
  1681              * java.lang.Object.
  1682              */
  1683             @Override
  1684             public Type visitTypeVar(TypeVar t, Void ignored) {
  1685                 if (t.bound.tag == TYPEVAR ||
  1686                     (!t.bound.isCompound() && !t.bound.isInterface())) {
  1687                     return t.bound;
  1688                 } else {
  1689                     return supertype(t.bound);
  1693             @Override
  1694             public Type visitArrayType(ArrayType t, Void ignored) {
  1695                 if (t.elemtype.isPrimitive() || isSameType(t.elemtype, syms.objectType))
  1696                     return arraySuperType();
  1697                 else
  1698                     return new ArrayType(supertype(t.elemtype), t.tsym);
  1701             @Override
  1702             public Type visitErrorType(ErrorType t, Void ignored) {
  1703                 return t;
  1705         };
  1706     // </editor-fold>
  1708     // <editor-fold defaultstate="collapsed" desc="interfaces">
  1709     /**
  1710      * Return the interfaces implemented by this class.
  1711      */
  1712     public List<Type> interfaces(Type t) {
  1713         return interfaces.visit(t);
  1715     // where
  1716         private UnaryVisitor<List<Type>> interfaces = new UnaryVisitor<List<Type>>() {
  1718             public List<Type> visitType(Type t, Void ignored) {
  1719                 return List.nil();
  1722             @Override
  1723             public List<Type> visitClassType(ClassType t, Void ignored) {
  1724                 if (t.interfaces_field == null) {
  1725                     List<Type> interfaces = ((ClassSymbol)t.tsym).getInterfaces();
  1726                     if (t.interfaces_field == null) {
  1727                         // If t.interfaces_field is null, then t must
  1728                         // be a parameterized type (not to be confused
  1729                         // with a generic type declaration).
  1730                         // Terminology:
  1731                         //    Parameterized type: List<String>
  1732                         //    Generic type declaration: class List<E> { ... }
  1733                         // So t corresponds to List<String> and
  1734                         // t.tsym.type corresponds to List<E>.
  1735                         // The reason t must be parameterized type is
  1736                         // that completion will happen as a side
  1737                         // effect of calling
  1738                         // ClassSymbol.getInterfaces.  Since
  1739                         // t.interfaces_field is null after
  1740                         // completion, we can assume that t is not the
  1741                         // type of a class/interface declaration.
  1742                         assert t != t.tsym.type : t.toString();
  1743                         List<Type> actuals = t.allparams();
  1744                         List<Type> formals = t.tsym.type.allparams();
  1745                         if (t.hasErasedSupertypes()) {
  1746                             t.interfaces_field = erasureRecursive(interfaces);
  1747                         } else if (formals.nonEmpty()) {
  1748                             t.interfaces_field =
  1749                                 upperBounds(subst(interfaces, formals, actuals));
  1751                         else {
  1752                             t.interfaces_field = interfaces;
  1756                 return t.interfaces_field;
  1759             @Override
  1760             public List<Type> visitTypeVar(TypeVar t, Void ignored) {
  1761                 if (t.bound.isCompound())
  1762                     return interfaces(t.bound);
  1764                 if (t.bound.isInterface())
  1765                     return List.of(t.bound);
  1767                 return List.nil();
  1769         };
  1770     // </editor-fold>
  1772     // <editor-fold defaultstate="collapsed" desc="isDerivedRaw">
  1773     Map<Type,Boolean> isDerivedRawCache = new HashMap<Type,Boolean>();
  1775     public boolean isDerivedRaw(Type t) {
  1776         Boolean result = isDerivedRawCache.get(t);
  1777         if (result == null) {
  1778             result = isDerivedRawInternal(t);
  1779             isDerivedRawCache.put(t, result);
  1781         return result;
  1784     public boolean isDerivedRawInternal(Type t) {
  1785         if (t.isErroneous())
  1786             return false;
  1787         return
  1788             t.isRaw() ||
  1789             supertype(t) != null && isDerivedRaw(supertype(t)) ||
  1790             isDerivedRaw(interfaces(t));
  1793     public boolean isDerivedRaw(List<Type> ts) {
  1794         List<Type> l = ts;
  1795         while (l.nonEmpty() && !isDerivedRaw(l.head)) l = l.tail;
  1796         return l.nonEmpty();
  1798     // </editor-fold>
  1800     // <editor-fold defaultstate="collapsed" desc="setBounds">
  1801     /**
  1802      * Set the bounds field of the given type variable to reflect a
  1803      * (possibly multiple) list of bounds.
  1804      * @param t                 a type variable
  1805      * @param bounds            the bounds, must be nonempty
  1806      * @param supertype         is objectType if all bounds are interfaces,
  1807      *                          null otherwise.
  1808      */
  1809     public void setBounds(TypeVar t, List<Type> bounds, Type supertype) {
  1810         if (bounds.tail.isEmpty())
  1811             t.bound = bounds.head;
  1812         else
  1813             t.bound = makeCompoundType(bounds, supertype);
  1814         t.rank_field = -1;
  1817     /**
  1818      * Same as {@link #setBounds(Type.TypeVar,List,Type)}, except that
  1819      * third parameter is computed directly.  Note that this test
  1820      * might cause a symbol completion.  Hence, this version of
  1821      * setBounds may not be called during a classfile read.
  1822      */
  1823     public void setBounds(TypeVar t, List<Type> bounds) {
  1824         Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ?
  1825             supertype(bounds.head) : null;
  1826         setBounds(t, bounds, supertype);
  1827         t.rank_field = -1;
  1829     // </editor-fold>
  1831     // <editor-fold defaultstate="collapsed" desc="getBounds">
  1832     /**
  1833      * Return list of bounds of the given type variable.
  1834      */
  1835     public List<Type> getBounds(TypeVar t) {
  1836         if (t.bound.isErroneous() || !t.bound.isCompound())
  1837             return List.of(t.bound);
  1838         else if ((erasure(t).tsym.flags() & INTERFACE) == 0)
  1839             return interfaces(t).prepend(supertype(t));
  1840         else
  1841             // No superclass was given in bounds.
  1842             // In this case, supertype is Object, erasure is first interface.
  1843             return interfaces(t);
  1845     // </editor-fold>
  1847     // <editor-fold defaultstate="collapsed" desc="classBound">
  1848     /**
  1849      * If the given type is a (possibly selected) type variable,
  1850      * return the bounding class of this type, otherwise return the
  1851      * type itself.
  1852      */
  1853     public Type classBound(Type t) {
  1854         return classBound.visit(t);
  1856     // where
  1857         private UnaryVisitor<Type> classBound = new UnaryVisitor<Type>() {
  1859             public Type visitType(Type t, Void ignored) {
  1860                 return t;
  1863             @Override
  1864             public Type visitClassType(ClassType t, Void ignored) {
  1865                 Type outer1 = classBound(t.getEnclosingType());
  1866                 if (outer1 != t.getEnclosingType())
  1867                     return new ClassType(outer1, t.getTypeArguments(), t.tsym);
  1868                 else
  1869                     return t;
  1872             @Override
  1873             public Type visitTypeVar(TypeVar t, Void ignored) {
  1874                 return classBound(supertype(t));
  1877             @Override
  1878             public Type visitErrorType(ErrorType t, Void ignored) {
  1879                 return t;
  1881         };
  1882     // </editor-fold>
  1884     // <editor-fold defaultstate="collapsed" desc="sub signature / override equivalence">
  1885     /**
  1886      * Returns true iff the first signature is a <em>sub
  1887      * signature</em> of the other.  This is <b>not</b> an equivalence
  1888      * relation.
  1890      * @see "The Java Language Specification, Third Ed. (8.4.2)."
  1891      * @see #overrideEquivalent(Type t, Type s)
  1892      * @param t first signature (possibly raw).
  1893      * @param s second signature (could be subjected to erasure).
  1894      * @return true if t is a sub signature of s.
  1895      */
  1896     public boolean isSubSignature(Type t, Type s) {
  1897         return hasSameArgs(t, s) || hasSameArgs(t, erasure(s));
  1900     /**
  1901      * Returns true iff these signatures are related by <em>override
  1902      * equivalence</em>.  This is the natural extension of
  1903      * isSubSignature to an equivalence relation.
  1905      * @see "The Java Language Specification, Third Ed. (8.4.2)."
  1906      * @see #isSubSignature(Type t, Type s)
  1907      * @param t a signature (possible raw, could be subjected to
  1908      * erasure).
  1909      * @param s a signature (possible raw, could be subjected to
  1910      * erasure).
  1911      * @return true if either argument is a sub signature of the other.
  1912      */
  1913     public boolean overrideEquivalent(Type t, Type s) {
  1914         return hasSameArgs(t, s) ||
  1915             hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s);
  1918     /**
  1919      * Does t have the same arguments as s?  It is assumed that both
  1920      * types are (possibly polymorphic) method types.  Monomorphic
  1921      * method types "have the same arguments", if their argument lists
  1922      * are equal.  Polymorphic method types "have the same arguments",
  1923      * if they have the same arguments after renaming all type
  1924      * variables of one to corresponding type variables in the other,
  1925      * where correspondence is by position in the type parameter list.
  1926      */
  1927     public boolean hasSameArgs(Type t, Type s) {
  1928         return hasSameArgs.visit(t, s);
  1930     // where
  1931         private TypeRelation hasSameArgs = new TypeRelation() {
  1933             public Boolean visitType(Type t, Type s) {
  1934                 throw new AssertionError();
  1937             @Override
  1938             public Boolean visitMethodType(MethodType t, Type s) {
  1939                 return s.tag == METHOD
  1940                     && containsTypeEquivalent(t.argtypes, s.getParameterTypes());
  1943             @Override
  1944             public Boolean visitForAll(ForAll t, Type s) {
  1945                 if (s.tag != FORALL)
  1946                     return false;
  1948                 ForAll forAll = (ForAll)s;
  1949                 return hasSameBounds(t, forAll)
  1950                     && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
  1953             @Override
  1954             public Boolean visitErrorType(ErrorType t, Type s) {
  1955                 return false;
  1957         };
  1958     // </editor-fold>
  1960     // <editor-fold defaultstate="collapsed" desc="subst">
  1961     public List<Type> subst(List<Type> ts,
  1962                             List<Type> from,
  1963                             List<Type> to) {
  1964         return new Subst(from, to).subst(ts);
  1967     /**
  1968      * Substitute all occurrences of a type in `from' with the
  1969      * corresponding type in `to' in 't'. Match lists `from' and `to'
  1970      * from the right: If lists have different length, discard leading
  1971      * elements of the longer list.
  1972      */
  1973     public Type subst(Type t, List<Type> from, List<Type> to) {
  1974         return new Subst(from, to).subst(t);
  1977     private class Subst extends UnaryVisitor<Type> {
  1978         List<Type> from;
  1979         List<Type> to;
  1981         public Subst(List<Type> from, List<Type> to) {
  1982             int fromLength = from.length();
  1983             int toLength = to.length();
  1984             while (fromLength > toLength) {
  1985                 fromLength--;
  1986                 from = from.tail;
  1988             while (fromLength < toLength) {
  1989                 toLength--;
  1990                 to = to.tail;
  1992             this.from = from;
  1993             this.to = to;
  1996         Type subst(Type t) {
  1997             if (from.tail == null)
  1998                 return t;
  1999             else
  2000                 return visit(t);
  2003         List<Type> subst(List<Type> ts) {
  2004             if (from.tail == null)
  2005                 return ts;
  2006             boolean wild = false;
  2007             if (ts.nonEmpty() && from.nonEmpty()) {
  2008                 Type head1 = subst(ts.head);
  2009                 List<Type> tail1 = subst(ts.tail);
  2010                 if (head1 != ts.head || tail1 != ts.tail)
  2011                     return tail1.prepend(head1);
  2013             return ts;
  2016         public Type visitType(Type t, Void ignored) {
  2017             return t;
  2020         @Override
  2021         public Type visitMethodType(MethodType t, Void ignored) {
  2022             List<Type> argtypes = subst(t.argtypes);
  2023             Type restype = subst(t.restype);
  2024             List<Type> thrown = subst(t.thrown);
  2025             if (argtypes == t.argtypes &&
  2026                 restype == t.restype &&
  2027                 thrown == t.thrown)
  2028                 return t;
  2029             else
  2030                 return new MethodType(argtypes, restype, thrown, t.tsym);
  2033         @Override
  2034         public Type visitTypeVar(TypeVar t, Void ignored) {
  2035             for (List<Type> from = this.from, to = this.to;
  2036                  from.nonEmpty();
  2037                  from = from.tail, to = to.tail) {
  2038                 if (t == from.head) {
  2039                     return to.head.withTypeVar(t);
  2042             return t;
  2045         @Override
  2046         public Type visitClassType(ClassType t, Void ignored) {
  2047             if (!t.isCompound()) {
  2048                 List<Type> typarams = t.getTypeArguments();
  2049                 List<Type> typarams1 = subst(typarams);
  2050                 Type outer = t.getEnclosingType();
  2051                 Type outer1 = subst(outer);
  2052                 if (typarams1 == typarams && outer1 == outer)
  2053                     return t;
  2054                 else
  2055                     return new ClassType(outer1, typarams1, t.tsym);
  2056             } else {
  2057                 Type st = subst(supertype(t));
  2058                 List<Type> is = upperBounds(subst(interfaces(t)));
  2059                 if (st == supertype(t) && is == interfaces(t))
  2060                     return t;
  2061                 else
  2062                     return makeCompoundType(is.prepend(st));
  2066         @Override
  2067         public Type visitWildcardType(WildcardType t, Void ignored) {
  2068             Type bound = t.type;
  2069             if (t.kind != BoundKind.UNBOUND)
  2070                 bound = subst(bound);
  2071             if (bound == t.type) {
  2072                 return t;
  2073             } else {
  2074                 if (t.isExtendsBound() && bound.isExtendsBound())
  2075                     bound = upperBound(bound);
  2076                 return new WildcardType(bound, t.kind, syms.boundClass, t.bound);
  2080         @Override
  2081         public Type visitArrayType(ArrayType t, Void ignored) {
  2082             Type elemtype = subst(t.elemtype);
  2083             if (elemtype == t.elemtype)
  2084                 return t;
  2085             else
  2086                 return new ArrayType(upperBound(elemtype), t.tsym);
  2089         @Override
  2090         public Type visitForAll(ForAll t, Void ignored) {
  2091             List<Type> tvars1 = substBounds(t.tvars, from, to);
  2092             Type qtype1 = subst(t.qtype);
  2093             if (tvars1 == t.tvars && qtype1 == t.qtype) {
  2094                 return t;
  2095             } else if (tvars1 == t.tvars) {
  2096                 return new ForAll(tvars1, qtype1);
  2097             } else {
  2098                 return new ForAll(tvars1, Types.this.subst(qtype1, t.tvars, tvars1));
  2102         @Override
  2103         public Type visitErrorType(ErrorType t, Void ignored) {
  2104             return t;
  2108     public List<Type> substBounds(List<Type> tvars,
  2109                                   List<Type> from,
  2110                                   List<Type> to) {
  2111         if (tvars.isEmpty())
  2112             return tvars;
  2113         if (tvars.tail.isEmpty())
  2114             // fast common case
  2115             return List.<Type>of(substBound((TypeVar)tvars.head, from, to));
  2116         ListBuffer<Type> newBoundsBuf = lb();
  2117         boolean changed = false;
  2118         // calculate new bounds
  2119         for (Type t : tvars) {
  2120             TypeVar tv = (TypeVar) t;
  2121             Type bound = subst(tv.bound, from, to);
  2122             if (bound != tv.bound)
  2123                 changed = true;
  2124             newBoundsBuf.append(bound);
  2126         if (!changed)
  2127             return tvars;
  2128         ListBuffer<Type> newTvars = lb();
  2129         // create new type variables without bounds
  2130         for (Type t : tvars) {
  2131             newTvars.append(new TypeVar(t.tsym, null, syms.botType));
  2133         // the new bounds should use the new type variables in place
  2134         // of the old
  2135         List<Type> newBounds = newBoundsBuf.toList();
  2136         from = tvars;
  2137         to = newTvars.toList();
  2138         for (; !newBounds.isEmpty(); newBounds = newBounds.tail) {
  2139             newBounds.head = subst(newBounds.head, from, to);
  2141         newBounds = newBoundsBuf.toList();
  2142         // set the bounds of new type variables to the new bounds
  2143         for (Type t : newTvars.toList()) {
  2144             TypeVar tv = (TypeVar) t;
  2145             tv.bound = newBounds.head;
  2146             newBounds = newBounds.tail;
  2148         return newTvars.toList();
  2151     public TypeVar substBound(TypeVar t, List<Type> from, List<Type> to) {
  2152         Type bound1 = subst(t.bound, from, to);
  2153         if (bound1 == t.bound)
  2154             return t;
  2155         else
  2156             return new TypeVar(t.tsym, bound1, syms.botType);
  2158     // </editor-fold>
  2160     // <editor-fold defaultstate="collapsed" desc="hasSameBounds">
  2161     /**
  2162      * Does t have the same bounds for quantified variables as s?
  2163      */
  2164     boolean hasSameBounds(ForAll t, ForAll s) {
  2165         List<Type> l1 = t.tvars;
  2166         List<Type> l2 = s.tvars;
  2167         while (l1.nonEmpty() && l2.nonEmpty() &&
  2168                isSameType(l1.head.getUpperBound(),
  2169                           subst(l2.head.getUpperBound(),
  2170                                 s.tvars,
  2171                                 t.tvars))) {
  2172             l1 = l1.tail;
  2173             l2 = l2.tail;
  2175         return l1.isEmpty() && l2.isEmpty();
  2177     // </editor-fold>
  2179     // <editor-fold defaultstate="collapsed" desc="newInstances">
  2180     /** Create new vector of type variables from list of variables
  2181      *  changing all recursive bounds from old to new list.
  2182      */
  2183     public List<Type> newInstances(List<Type> tvars) {
  2184         List<Type> tvars1 = Type.map(tvars, newInstanceFun);
  2185         for (List<Type> l = tvars1; l.nonEmpty(); l = l.tail) {
  2186             TypeVar tv = (TypeVar) l.head;
  2187             tv.bound = subst(tv.bound, tvars, tvars1);
  2189         return tvars1;
  2191     static private Mapping newInstanceFun = new Mapping("newInstanceFun") {
  2192             public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound()); }
  2193         };
  2194     // </editor-fold>
  2196     // <editor-fold defaultstate="collapsed" desc="createErrorType">
  2197     public Type createErrorType(Type originalType) {
  2198         return new ErrorType(originalType, syms.errSymbol);
  2201     public Type createErrorType(ClassSymbol c, Type originalType) {
  2202         return new ErrorType(c, originalType);
  2205     public Type createErrorType(Name name, TypeSymbol container, Type originalType) {
  2206         return new ErrorType(name, container, originalType);
  2208     // </editor-fold>
  2210     // <editor-fold defaultstate="collapsed" desc="rank">
  2211     /**
  2212      * The rank of a class is the length of the longest path between
  2213      * the class and java.lang.Object in the class inheritance
  2214      * graph. Undefined for all but reference types.
  2215      */
  2216     public int rank(Type t) {
  2217         switch(t.tag) {
  2218         case CLASS: {
  2219             ClassType cls = (ClassType)t;
  2220             if (cls.rank_field < 0) {
  2221                 Name fullname = cls.tsym.getQualifiedName();
  2222                 if (fullname == names.java_lang_Object)
  2223                     cls.rank_field = 0;
  2224                 else {
  2225                     int r = rank(supertype(cls));
  2226                     for (List<Type> l = interfaces(cls);
  2227                          l.nonEmpty();
  2228                          l = l.tail) {
  2229                         if (rank(l.head) > r)
  2230                             r = rank(l.head);
  2232                     cls.rank_field = r + 1;
  2235             return cls.rank_field;
  2237         case TYPEVAR: {
  2238             TypeVar tvar = (TypeVar)t;
  2239             if (tvar.rank_field < 0) {
  2240                 int r = rank(supertype(tvar));
  2241                 for (List<Type> l = interfaces(tvar);
  2242                      l.nonEmpty();
  2243                      l = l.tail) {
  2244                     if (rank(l.head) > r) r = rank(l.head);
  2246                 tvar.rank_field = r + 1;
  2248             return tvar.rank_field;
  2250         case ERROR:
  2251             return 0;
  2252         default:
  2253             throw new AssertionError();
  2256     // </editor-fold>
  2258     // <editor-fold defaultstate="collapsed" desc="printType">
  2259     /**
  2260      * Visitor for generating a string representation of a given type
  2261      * accordingly to a given locale
  2262      */
  2263     public String toString(Type t, Locale locale) {
  2264         return typePrinter.visit(t, locale);
  2266     // where
  2267     private TypePrinter typePrinter = new TypePrinter();
  2269     public class TypePrinter extends DefaultTypeVisitor<String, Locale> {
  2271         public String visit(List<Type> ts, Locale locale) {
  2272             ListBuffer<String> sbuf = lb();
  2273             for (Type t : ts) {
  2274                 sbuf.append(visit(t, locale));
  2276             return sbuf.toList().toString();
  2279         @Override
  2280         public String visitCapturedType(CapturedType t, Locale locale) {
  2281             return messages.getLocalizedString("compiler.misc.type.captureof",
  2282                         (t.hashCode() & 0xFFFFFFFFL) % Type.CapturedType.PRIME,
  2283                         visit(t.wildcard, locale));
  2286         @Override
  2287         public String visitForAll(ForAll t, Locale locale) {
  2288             return "<" + visit(t.tvars, locale) + ">" + visit(t.qtype, locale);
  2291         @Override
  2292         public String visitUndetVar(UndetVar t, Locale locale) {
  2293             if (t.inst != null) {
  2294                 return visit(t.inst, locale);
  2295             } else {
  2296                 return visit(t.qtype, locale) + "?";
  2300         @Override
  2301         public String visitArrayType(ArrayType t, Locale locale) {
  2302             return visit(t.elemtype, locale) + "[]";
  2305         @Override
  2306         public String visitClassType(ClassType t, Locale locale) {
  2307             StringBuffer buf = new StringBuffer();
  2308             if (t.getEnclosingType().tag == CLASS && t.tsym.owner.kind == Kinds.TYP) {
  2309                 buf.append(visit(t.getEnclosingType(), locale));
  2310                 buf.append(".");
  2311                 buf.append(className(t, false, locale));
  2312             } else {
  2313                 buf.append(className(t, true, locale));
  2315             if (t.getTypeArguments().nonEmpty()) {
  2316                 buf.append('<');
  2317                 buf.append(visit(t.getTypeArguments(), locale));
  2318                 buf.append(">");
  2320             return buf.toString();
  2323         @Override
  2324         public String visitMethodType(MethodType t, Locale locale) {
  2325             return "(" + printMethodArgs(t.argtypes, false, locale) + ")" + visit(t.restype, locale);
  2328         @Override
  2329         public String visitPackageType(PackageType t, Locale locale) {
  2330             return t.tsym.getQualifiedName().toString();
  2333         @Override
  2334         public String visitWildcardType(WildcardType t, Locale locale) {
  2335             StringBuffer s = new StringBuffer();
  2336             s.append(t.kind);
  2337             if (t.kind != UNBOUND) {
  2338                 s.append(visit(t.type, locale));
  2340             return s.toString();
  2344         public String visitType(Type t, Locale locale) {
  2345             String s = (t.tsym == null || t.tsym.name == null)
  2346                     ? messages.getLocalizedString("compiler.misc.type.none")
  2347                     : t.tsym.name.toString();
  2348             return s;
  2351         protected String className(ClassType t, boolean longform, Locale locale) {
  2352             Symbol sym = t.tsym;
  2353             if (sym.name.length() == 0 && (sym.flags() & COMPOUND) != 0) {
  2354                 StringBuffer s = new StringBuffer(visit(supertype(t), locale));
  2355                 for (List<Type> is = interfaces(t); is.nonEmpty(); is = is.tail) {
  2356                     s.append("&");
  2357                     s.append(visit(is.head, locale));
  2359                 return s.toString();
  2360             } else if (sym.name.length() == 0) {
  2361                 String s;
  2362                 ClassType norm = (ClassType) t.tsym.type;
  2363                 if (norm == null) {
  2364                     s = getLocalizedString(locale, "compiler.misc.anonymous.class", (Object) null);
  2365                 } else if (interfaces(norm).nonEmpty()) {
  2366                     s = getLocalizedString(locale, "compiler.misc.anonymous.class",
  2367                             visit(interfaces(norm).head, locale));
  2368                 } else {
  2369                     s = getLocalizedString(locale, "compiler.misc.anonymous.class",
  2370                             visit(supertype(norm), locale));
  2372                 return s;
  2373             } else if (longform) {
  2374                 return sym.getQualifiedName().toString();
  2375             } else {
  2376                 return sym.name.toString();
  2380         protected String printMethodArgs(List<Type> args, boolean varArgs, Locale locale) {
  2381             if (!varArgs) {
  2382                 return visit(args, locale);
  2383             } else {
  2384                 StringBuffer buf = new StringBuffer();
  2385                 while (args.tail.nonEmpty()) {
  2386                     buf.append(visit(args.head, locale));
  2387                     args = args.tail;
  2388                     buf.append(',');
  2390                 if (args.head.tag == ARRAY) {
  2391                     buf.append(visit(((ArrayType) args.head).elemtype, locale));
  2392                     buf.append("...");
  2393                 } else {
  2394                     buf.append(visit(args.head, locale));
  2396                 return buf.toString();
  2400         protected String getLocalizedString(Locale locale, String key, Object... args) {
  2401             return messages.getLocalizedString(key, args);
  2403     };
  2404     // </editor-fold>
  2406     // <editor-fold defaultstate="collapsed" desc="printSymbol">
  2407     /**
  2408      * Visitor for generating a string representation of a given symbol
  2409      * accordingly to a given locale
  2410      */
  2411     public String toString(Symbol t, Locale locale) {
  2412         return symbolPrinter.visit(t, locale);
  2414     // where
  2415     private SymbolPrinter symbolPrinter = new SymbolPrinter();
  2417     public class SymbolPrinter extends DefaultSymbolVisitor<String, Locale> {
  2419         @Override
  2420         public String visitClassSymbol(ClassSymbol sym, Locale locale) {
  2421             return sym.name.isEmpty()
  2422                     ? getLocalizedString(locale, "compiler.misc.anonymous.class", sym.flatname)
  2423                     : sym.fullname.toString();
  2426         @Override
  2427         public String visitMethodSymbol(MethodSymbol s, Locale locale) {
  2428             if ((s.flags() & BLOCK) != 0) {
  2429                 return s.owner.name.toString();
  2430             } else {
  2431                 String ms = (s.name == names.init)
  2432                         ? s.owner.name.toString()
  2433                         : s.name.toString();
  2434                 if (s.type != null) {
  2435                     if (s.type.tag == FORALL) {
  2436                         ms = "<" + typePrinter.visit(s.type.getTypeArguments(), locale) + ">" + ms;
  2438                     ms += "(" + typePrinter.printMethodArgs(
  2439                             s.type.getParameterTypes(),
  2440                             (s.flags() & VARARGS) != 0,
  2441                             locale) + ")";
  2443                 return ms;
  2447         @Override
  2448         public String visitOperatorSymbol(OperatorSymbol s, Locale locale) {
  2449             return visitMethodSymbol(s, locale);
  2452         @Override
  2453         public String visitPackageSymbol(PackageSymbol s, Locale locale) {
  2454             return s.name.isEmpty()
  2455                     ? getLocalizedString(locale, "compiler.misc.unnamed.package")
  2456                     : s.fullname.toString();
  2459         @Override
  2460         public String visitSymbol(Symbol s, Locale locale) {
  2461             return s.name.toString();
  2464         public String visit(List<Symbol> ts, Locale locale) {
  2465             ListBuffer<String> sbuf = lb();
  2466             for (Symbol t : ts) {
  2467                 sbuf.append(visit(t, locale));
  2469             return sbuf.toList().toString();
  2472         protected String getLocalizedString(Locale locale, String key, Object... args) {
  2473             return messages.getLocalizedString(key, args);
  2475     };
  2476     // </editor-fold>
  2478     // <editor-fold defaultstate="collapsed" desc="toString">
  2479     /**
  2480      * This toString is slightly more descriptive than the one on Type.
  2482      * @deprecated Types.toString(Type t, Locale l) provides better support
  2483      * for localization
  2484      */
  2485     @Deprecated
  2486     public String toString(Type t) {
  2487         if (t.tag == FORALL) {
  2488             ForAll forAll = (ForAll)t;
  2489             return typaramsString(forAll.tvars) + forAll.qtype;
  2491         return "" + t;
  2493     // where
  2494         private String typaramsString(List<Type> tvars) {
  2495             StringBuffer s = new StringBuffer();
  2496             s.append('<');
  2497             boolean first = true;
  2498             for (Type t : tvars) {
  2499                 if (!first) s.append(", ");
  2500                 first = false;
  2501                 appendTyparamString(((TypeVar)t), s);
  2503             s.append('>');
  2504             return s.toString();
  2506         private void appendTyparamString(TypeVar t, StringBuffer buf) {
  2507             buf.append(t);
  2508             if (t.bound == null ||
  2509                 t.bound.tsym.getQualifiedName() == names.java_lang_Object)
  2510                 return;
  2511             buf.append(" extends "); // Java syntax; no need for i18n
  2512             Type bound = t.bound;
  2513             if (!bound.isCompound()) {
  2514                 buf.append(bound);
  2515             } else if ((erasure(t).tsym.flags() & INTERFACE) == 0) {
  2516                 buf.append(supertype(t));
  2517                 for (Type intf : interfaces(t)) {
  2518                     buf.append('&');
  2519                     buf.append(intf);
  2521             } else {
  2522                 // No superclass was given in bounds.
  2523                 // In this case, supertype is Object, erasure is first interface.
  2524                 boolean first = true;
  2525                 for (Type intf : interfaces(t)) {
  2526                     if (!first) buf.append('&');
  2527                     first = false;
  2528                     buf.append(intf);
  2532     // </editor-fold>
  2534     // <editor-fold defaultstate="collapsed" desc="Determining least upper bounds of types">
  2535     /**
  2536      * A cache for closures.
  2538      * <p>A closure is a list of all the supertypes and interfaces of
  2539      * a class or interface type, ordered by ClassSymbol.precedes
  2540      * (that is, subclasses come first, arbitrary but fixed
  2541      * otherwise).
  2542      */
  2543     private Map<Type,List<Type>> closureCache = new HashMap<Type,List<Type>>();
  2545     /**
  2546      * Returns the closure of a class or interface type.
  2547      */
  2548     public List<Type> closure(Type t) {
  2549         List<Type> cl = closureCache.get(t);
  2550         if (cl == null) {
  2551             Type st = supertype(t);
  2552             if (!t.isCompound()) {
  2553                 if (st.tag == CLASS) {
  2554                     cl = insert(closure(st), t);
  2555                 } else if (st.tag == TYPEVAR) {
  2556                     cl = closure(st).prepend(t);
  2557                 } else {
  2558                     cl = List.of(t);
  2560             } else {
  2561                 cl = closure(supertype(t));
  2563             for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail)
  2564                 cl = union(cl, closure(l.head));
  2565             closureCache.put(t, cl);
  2567         return cl;
  2570     /**
  2571      * Insert a type in a closure
  2572      */
  2573     public List<Type> insert(List<Type> cl, Type t) {
  2574         if (cl.isEmpty() || t.tsym.precedes(cl.head.tsym, this)) {
  2575             return cl.prepend(t);
  2576         } else if (cl.head.tsym.precedes(t.tsym, this)) {
  2577             return insert(cl.tail, t).prepend(cl.head);
  2578         } else {
  2579             return cl;
  2583     /**
  2584      * Form the union of two closures
  2585      */
  2586     public List<Type> union(List<Type> cl1, List<Type> cl2) {
  2587         if (cl1.isEmpty()) {
  2588             return cl2;
  2589         } else if (cl2.isEmpty()) {
  2590             return cl1;
  2591         } else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) {
  2592             return union(cl1.tail, cl2).prepend(cl1.head);
  2593         } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) {
  2594             return union(cl1, cl2.tail).prepend(cl2.head);
  2595         } else {
  2596             return union(cl1.tail, cl2.tail).prepend(cl1.head);
  2600     /**
  2601      * Intersect two closures
  2602      */
  2603     public List<Type> intersect(List<Type> cl1, List<Type> cl2) {
  2604         if (cl1 == cl2)
  2605             return cl1;
  2606         if (cl1.isEmpty() || cl2.isEmpty())
  2607             return List.nil();
  2608         if (cl1.head.tsym.precedes(cl2.head.tsym, this))
  2609             return intersect(cl1.tail, cl2);
  2610         if (cl2.head.tsym.precedes(cl1.head.tsym, this))
  2611             return intersect(cl1, cl2.tail);
  2612         if (isSameType(cl1.head, cl2.head))
  2613             return intersect(cl1.tail, cl2.tail).prepend(cl1.head);
  2614         if (cl1.head.tsym == cl2.head.tsym &&
  2615             cl1.head.tag == CLASS && cl2.head.tag == CLASS) {
  2616             if (cl1.head.isParameterized() && cl2.head.isParameterized()) {
  2617                 Type merge = merge(cl1.head,cl2.head);
  2618                 return intersect(cl1.tail, cl2.tail).prepend(merge);
  2620             if (cl1.head.isRaw() || cl2.head.isRaw())
  2621                 return intersect(cl1.tail, cl2.tail).prepend(erasure(cl1.head));
  2623         return intersect(cl1.tail, cl2.tail);
  2625     // where
  2626         class TypePair {
  2627             final Type t1;
  2628             final Type t2;
  2629             TypePair(Type t1, Type t2) {
  2630                 this.t1 = t1;
  2631                 this.t2 = t2;
  2633             @Override
  2634             public int hashCode() {
  2635                 return 127 * Types.this.hashCode(t1) + Types.this.hashCode(t2);
  2637             @Override
  2638             public boolean equals(Object obj) {
  2639                 if (!(obj instanceof TypePair))
  2640                     return false;
  2641                 TypePair typePair = (TypePair)obj;
  2642                 return isSameType(t1, typePair.t1)
  2643                     && isSameType(t2, typePair.t2);
  2646         Set<TypePair> mergeCache = new HashSet<TypePair>();
  2647         private Type merge(Type c1, Type c2) {
  2648             ClassType class1 = (ClassType) c1;
  2649             List<Type> act1 = class1.getTypeArguments();
  2650             ClassType class2 = (ClassType) c2;
  2651             List<Type> act2 = class2.getTypeArguments();
  2652             ListBuffer<Type> merged = new ListBuffer<Type>();
  2653             List<Type> typarams = class1.tsym.type.getTypeArguments();
  2655             while (act1.nonEmpty() && act2.nonEmpty() && typarams.nonEmpty()) {
  2656                 if (containsType(act1.head, act2.head)) {
  2657                     merged.append(act1.head);
  2658                 } else if (containsType(act2.head, act1.head)) {
  2659                     merged.append(act2.head);
  2660                 } else {
  2661                     TypePair pair = new TypePair(c1, c2);
  2662                     Type m;
  2663                     if (mergeCache.add(pair)) {
  2664                         m = new WildcardType(lub(upperBound(act1.head),
  2665                                                  upperBound(act2.head)),
  2666                                              BoundKind.EXTENDS,
  2667                                              syms.boundClass);
  2668                         mergeCache.remove(pair);
  2669                     } else {
  2670                         m = new WildcardType(syms.objectType,
  2671                                              BoundKind.UNBOUND,
  2672                                              syms.boundClass);
  2674                     merged.append(m.withTypeVar(typarams.head));
  2676                 act1 = act1.tail;
  2677                 act2 = act2.tail;
  2678                 typarams = typarams.tail;
  2680             assert(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
  2681             return new ClassType(class1.getEnclosingType(), merged.toList(), class1.tsym);
  2684     /**
  2685      * Return the minimum type of a closure, a compound type if no
  2686      * unique minimum exists.
  2687      */
  2688     private Type compoundMin(List<Type> cl) {
  2689         if (cl.isEmpty()) return syms.objectType;
  2690         List<Type> compound = closureMin(cl);
  2691         if (compound.isEmpty())
  2692             return null;
  2693         else if (compound.tail.isEmpty())
  2694             return compound.head;
  2695         else
  2696             return makeCompoundType(compound);
  2699     /**
  2700      * Return the minimum types of a closure, suitable for computing
  2701      * compoundMin or glb.
  2702      */
  2703     private List<Type> closureMin(List<Type> cl) {
  2704         ListBuffer<Type> classes = lb();
  2705         ListBuffer<Type> interfaces = lb();
  2706         while (!cl.isEmpty()) {
  2707             Type current = cl.head;
  2708             if (current.isInterface())
  2709                 interfaces.append(current);
  2710             else
  2711                 classes.append(current);
  2712             ListBuffer<Type> candidates = lb();
  2713             for (Type t : cl.tail) {
  2714                 if (!isSubtypeNoCapture(current, t))
  2715                     candidates.append(t);
  2717             cl = candidates.toList();
  2719         return classes.appendList(interfaces).toList();
  2722     /**
  2723      * Return the least upper bound of pair of types.  if the lub does
  2724      * not exist return null.
  2725      */
  2726     public Type lub(Type t1, Type t2) {
  2727         return lub(List.of(t1, t2));
  2730     /**
  2731      * Return the least upper bound (lub) of set of types.  If the lub
  2732      * does not exist return the type of null (bottom).
  2733      */
  2734     public Type lub(List<Type> ts) {
  2735         final int ARRAY_BOUND = 1;
  2736         final int CLASS_BOUND = 2;
  2737         int boundkind = 0;
  2738         for (Type t : ts) {
  2739             switch (t.tag) {
  2740             case CLASS:
  2741                 boundkind |= CLASS_BOUND;
  2742                 break;
  2743             case ARRAY:
  2744                 boundkind |= ARRAY_BOUND;
  2745                 break;
  2746             case  TYPEVAR:
  2747                 do {
  2748                     t = t.getUpperBound();
  2749                 } while (t.tag == TYPEVAR);
  2750                 if (t.tag == ARRAY) {
  2751                     boundkind |= ARRAY_BOUND;
  2752                 } else {
  2753                     boundkind |= CLASS_BOUND;
  2755                 break;
  2756             default:
  2757                 if (t.isPrimitive())
  2758                     return syms.errType;
  2761         switch (boundkind) {
  2762         case 0:
  2763             return syms.botType;
  2765         case ARRAY_BOUND:
  2766             // calculate lub(A[], B[])
  2767             List<Type> elements = Type.map(ts, elemTypeFun);
  2768             for (Type t : elements) {
  2769                 if (t.isPrimitive()) {
  2770                     // if a primitive type is found, then return
  2771                     // arraySuperType unless all the types are the
  2772                     // same
  2773                     Type first = ts.head;
  2774                     for (Type s : ts.tail) {
  2775                         if (!isSameType(first, s)) {
  2776                              // lub(int[], B[]) is Cloneable & Serializable
  2777                             return arraySuperType();
  2780                     // all the array types are the same, return one
  2781                     // lub(int[], int[]) is int[]
  2782                     return first;
  2785             // lub(A[], B[]) is lub(A, B)[]
  2786             return new ArrayType(lub(elements), syms.arrayClass);
  2788         case CLASS_BOUND:
  2789             // calculate lub(A, B)
  2790             while (ts.head.tag != CLASS && ts.head.tag != TYPEVAR)
  2791                 ts = ts.tail;
  2792             assert !ts.isEmpty();
  2793             List<Type> cl = closure(ts.head);
  2794             for (Type t : ts.tail) {
  2795                 if (t.tag == CLASS || t.tag == TYPEVAR)
  2796                     cl = intersect(cl, closure(t));
  2798             return compoundMin(cl);
  2800         default:
  2801             // calculate lub(A, B[])
  2802             List<Type> classes = List.of(arraySuperType());
  2803             for (Type t : ts) {
  2804                 if (t.tag != ARRAY) // Filter out any arrays
  2805                     classes = classes.prepend(t);
  2807             // lub(A, B[]) is lub(A, arraySuperType)
  2808             return lub(classes);
  2811     // where
  2812         private Type arraySuperType = null;
  2813         private Type arraySuperType() {
  2814             // initialized lazily to avoid problems during compiler startup
  2815             if (arraySuperType == null) {
  2816                 synchronized (this) {
  2817                     if (arraySuperType == null) {
  2818                         // JLS 10.8: all arrays implement Cloneable and Serializable.
  2819                         arraySuperType = makeCompoundType(List.of(syms.serializableType,
  2820                                                                   syms.cloneableType),
  2821                                                           syms.objectType);
  2825             return arraySuperType;
  2827     // </editor-fold>
  2829     // <editor-fold defaultstate="collapsed" desc="Greatest lower bound">
  2830     public Type glb(Type t, Type s) {
  2831         if (s == null)
  2832             return t;
  2833         else if (isSubtypeNoCapture(t, s))
  2834             return t;
  2835         else if (isSubtypeNoCapture(s, t))
  2836             return s;
  2838         List<Type> closure = union(closure(t), closure(s));
  2839         List<Type> bounds = closureMin(closure);
  2841         if (bounds.isEmpty()) {             // length == 0
  2842             return syms.objectType;
  2843         } else if (bounds.tail.isEmpty()) { // length == 1
  2844             return bounds.head;
  2845         } else {                            // length > 1
  2846             int classCount = 0;
  2847             for (Type bound : bounds)
  2848                 if (!bound.isInterface())
  2849                     classCount++;
  2850             if (classCount > 1)
  2851                 return createErrorType(t);
  2853         return makeCompoundType(bounds);
  2855     // </editor-fold>
  2857     // <editor-fold defaultstate="collapsed" desc="hashCode">
  2858     /**
  2859      * Compute a hash code on a type.
  2860      */
  2861     public static int hashCode(Type t) {
  2862         return hashCode.visit(t);
  2864     // where
  2865         private static final UnaryVisitor<Integer> hashCode = new UnaryVisitor<Integer>() {
  2867             public Integer visitType(Type t, Void ignored) {
  2868                 return t.tag;
  2871             @Override
  2872             public Integer visitClassType(ClassType t, Void ignored) {
  2873                 int result = visit(t.getEnclosingType());
  2874                 result *= 127;
  2875                 result += t.tsym.flatName().hashCode();
  2876                 for (Type s : t.getTypeArguments()) {
  2877                     result *= 127;
  2878                     result += visit(s);
  2880                 return result;
  2883             @Override
  2884             public Integer visitWildcardType(WildcardType t, Void ignored) {
  2885                 int result = t.kind.hashCode();
  2886                 if (t.type != null) {
  2887                     result *= 127;
  2888                     result += visit(t.type);
  2890                 return result;
  2893             @Override
  2894             public Integer visitArrayType(ArrayType t, Void ignored) {
  2895                 return visit(t.elemtype) + 12;
  2898             @Override
  2899             public Integer visitTypeVar(TypeVar t, Void ignored) {
  2900                 return System.identityHashCode(t.tsym);
  2903             @Override
  2904             public Integer visitUndetVar(UndetVar t, Void ignored) {
  2905                 return System.identityHashCode(t);
  2908             @Override
  2909             public Integer visitErrorType(ErrorType t, Void ignored) {
  2910                 return 0;
  2912         };
  2913     // </editor-fold>
  2915     // <editor-fold defaultstate="collapsed" desc="Return-Type-Substitutable">
  2916     /**
  2917      * Does t have a result that is a subtype of the result type of s,
  2918      * suitable for covariant returns?  It is assumed that both types
  2919      * are (possibly polymorphic) method types.  Monomorphic method
  2920      * types are handled in the obvious way.  Polymorphic method types
  2921      * require renaming all type variables of one to corresponding
  2922      * type variables in the other, where correspondence is by
  2923      * position in the type parameter list. */
  2924     public boolean resultSubtype(Type t, Type s, Warner warner) {
  2925         List<Type> tvars = t.getTypeArguments();
  2926         List<Type> svars = s.getTypeArguments();
  2927         Type tres = t.getReturnType();
  2928         Type sres = subst(s.getReturnType(), svars, tvars);
  2929         return covariantReturnType(tres, sres, warner);
  2932     /**
  2933      * Return-Type-Substitutable.
  2934      * @see <a href="http://java.sun.com/docs/books/jls/">The Java
  2935      * Language Specification, Third Ed. (8.4.5)</a>
  2936      */
  2937     public boolean returnTypeSubstitutable(Type r1, Type r2) {
  2938         if (hasSameArgs(r1, r2))
  2939             return resultSubtype(r1, r2, Warner.noWarnings);
  2940         else
  2941             return covariantReturnType(r1.getReturnType(),
  2942                                        erasure(r2.getReturnType()),
  2943                                        Warner.noWarnings);
  2946     public boolean returnTypeSubstitutable(Type r1,
  2947                                            Type r2, Type r2res,
  2948                                            Warner warner) {
  2949         if (isSameType(r1.getReturnType(), r2res))
  2950             return true;
  2951         if (r1.getReturnType().isPrimitive() || r2res.isPrimitive())
  2952             return false;
  2954         if (hasSameArgs(r1, r2))
  2955             return covariantReturnType(r1.getReturnType(), r2res, warner);
  2956         if (!source.allowCovariantReturns())
  2957             return false;
  2958         if (isSubtypeUnchecked(r1.getReturnType(), r2res, warner))
  2959             return true;
  2960         if (!isSubtype(r1.getReturnType(), erasure(r2res)))
  2961             return false;
  2962         warner.warnUnchecked();
  2963         return true;
  2966     /**
  2967      * Is t an appropriate return type in an overrider for a
  2968      * method that returns s?
  2969      */
  2970     public boolean covariantReturnType(Type t, Type s, Warner warner) {
  2971         return
  2972             isSameType(t, s) ||
  2973             source.allowCovariantReturns() &&
  2974             !t.isPrimitive() &&
  2975             !s.isPrimitive() &&
  2976             isAssignable(t, s, warner);
  2978     // </editor-fold>
  2980     // <editor-fold defaultstate="collapsed" desc="Box/unbox support">
  2981     /**
  2982      * Return the class that boxes the given primitive.
  2983      */
  2984     public ClassSymbol boxedClass(Type t) {
  2985         return reader.enterClass(syms.boxedName[t.tag]);
  2988     /**
  2989      * Return the primitive type corresponding to a boxed type.
  2990      */
  2991     public Type unboxedType(Type t) {
  2992         if (allowBoxing) {
  2993             for (int i=0; i<syms.boxedName.length; i++) {
  2994                 Name box = syms.boxedName[i];
  2995                 if (box != null &&
  2996                     asSuper(t, reader.enterClass(box)) != null)
  2997                     return syms.typeOfTag[i];
  3000         return Type.noType;
  3002     // </editor-fold>
  3004     // <editor-fold defaultstate="collapsed" desc="Capture conversion">
  3005     /*
  3006      * JLS 3rd Ed. 5.1.10 Capture Conversion:
  3008      * Let G name a generic type declaration with n formal type
  3009      * parameters A1 ... An with corresponding bounds U1 ... Un. There
  3010      * exists a capture conversion from G<T1 ... Tn> to G<S1 ... Sn>,
  3011      * where, for 1 <= i <= n:
  3013      * + If Ti is a wildcard type argument (4.5.1) of the form ? then
  3014      *   Si is a fresh type variable whose upper bound is
  3015      *   Ui[A1 := S1, ..., An := Sn] and whose lower bound is the null
  3016      *   type.
  3018      * + If Ti is a wildcard type argument of the form ? extends Bi,
  3019      *   then Si is a fresh type variable whose upper bound is
  3020      *   glb(Bi, Ui[A1 := S1, ..., An := Sn]) and whose lower bound is
  3021      *   the null type, where glb(V1,... ,Vm) is V1 & ... & Vm. It is
  3022      *   a compile-time error if for any two classes (not interfaces)
  3023      *   Vi and Vj,Vi is not a subclass of Vj or vice versa.
  3025      * + If Ti is a wildcard type argument of the form ? super Bi,
  3026      *   then Si is a fresh type variable whose upper bound is
  3027      *   Ui[A1 := S1, ..., An := Sn] and whose lower bound is Bi.
  3029      * + Otherwise, Si = Ti.
  3031      * Capture conversion on any type other than a parameterized type
  3032      * (4.5) acts as an identity conversion (5.1.1). Capture
  3033      * conversions never require a special action at run time and
  3034      * therefore never throw an exception at run time.
  3036      * Capture conversion is not applied recursively.
  3037      */
  3038     /**
  3039      * Capture conversion as specified by JLS 3rd Ed.
  3040      */
  3041     public Type capture(Type t) {
  3042         if (t.tag != CLASS)
  3043             return t;
  3044         ClassType cls = (ClassType)t;
  3045         if (cls.isRaw() || !cls.isParameterized())
  3046             return cls;
  3048         ClassType G = (ClassType)cls.asElement().asType();
  3049         List<Type> A = G.getTypeArguments();
  3050         List<Type> T = cls.getTypeArguments();
  3051         List<Type> S = freshTypeVariables(T);
  3053         List<Type> currentA = A;
  3054         List<Type> currentT = T;
  3055         List<Type> currentS = S;
  3056         boolean captured = false;
  3057         while (!currentA.isEmpty() &&
  3058                !currentT.isEmpty() &&
  3059                !currentS.isEmpty()) {
  3060             if (currentS.head != currentT.head) {
  3061                 captured = true;
  3062                 WildcardType Ti = (WildcardType)currentT.head;
  3063                 Type Ui = currentA.head.getUpperBound();
  3064                 CapturedType Si = (CapturedType)currentS.head;
  3065                 if (Ui == null)
  3066                     Ui = syms.objectType;
  3067                 switch (Ti.kind) {
  3068                 case UNBOUND:
  3069                     Si.bound = subst(Ui, A, S);
  3070                     Si.lower = syms.botType;
  3071                     break;
  3072                 case EXTENDS:
  3073                     Si.bound = glb(Ti.getExtendsBound(), subst(Ui, A, S));
  3074                     Si.lower = syms.botType;
  3075                     break;
  3076                 case SUPER:
  3077                     Si.bound = subst(Ui, A, S);
  3078                     Si.lower = Ti.getSuperBound();
  3079                     break;
  3081                 if (Si.bound == Si.lower)
  3082                     currentS.head = Si.bound;
  3084             currentA = currentA.tail;
  3085             currentT = currentT.tail;
  3086             currentS = currentS.tail;
  3088         if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty())
  3089             return erasure(t); // some "rare" type involved
  3091         if (captured)
  3092             return new ClassType(cls.getEnclosingType(), S, cls.tsym);
  3093         else
  3094             return t;
  3096     // where
  3097         private List<Type> freshTypeVariables(List<Type> types) {
  3098             ListBuffer<Type> result = lb();
  3099             for (Type t : types) {
  3100                 if (t.tag == WILDCARD) {
  3101                     Type bound = ((WildcardType)t).getExtendsBound();
  3102                     if (bound == null)
  3103                         bound = syms.objectType;
  3104                     result.append(new CapturedType(capturedName,
  3105                                                    syms.noSymbol,
  3106                                                    bound,
  3107                                                    syms.botType,
  3108                                                    (WildcardType)t));
  3109                 } else {
  3110                     result.append(t);
  3113             return result.toList();
  3115     // </editor-fold>
  3117     // <editor-fold defaultstate="collapsed" desc="Internal utility methods">
  3118     private List<Type> upperBounds(List<Type> ss) {
  3119         if (ss.isEmpty()) return ss;
  3120         Type head = upperBound(ss.head);
  3121         List<Type> tail = upperBounds(ss.tail);
  3122         if (head != ss.head || tail != ss.tail)
  3123             return tail.prepend(head);
  3124         else
  3125             return ss;
  3128     private boolean sideCast(Type from, Type to, Warner warn) {
  3129         // We are casting from type $from$ to type $to$, which are
  3130         // non-final unrelated types.  This method
  3131         // tries to reject a cast by transferring type parameters
  3132         // from $to$ to $from$ by common superinterfaces.
  3133         boolean reverse = false;
  3134         Type target = to;
  3135         if ((to.tsym.flags() & INTERFACE) == 0) {
  3136             assert (from.tsym.flags() & INTERFACE) != 0;
  3137             reverse = true;
  3138             to = from;
  3139             from = target;
  3141         List<Type> commonSupers = superClosure(to, erasure(from));
  3142         boolean giveWarning = commonSupers.isEmpty();
  3143         // The arguments to the supers could be unified here to
  3144         // get a more accurate analysis
  3145         while (commonSupers.nonEmpty()) {
  3146             Type t1 = asSuper(from, commonSupers.head.tsym);
  3147             Type t2 = commonSupers.head; // same as asSuper(to, commonSupers.head.tsym);
  3148             if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
  3149                 return false;
  3150             giveWarning = giveWarning || (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2));
  3151             commonSupers = commonSupers.tail;
  3153         if (giveWarning && !isReifiable(to))
  3154             warn.warnUnchecked();
  3155         if (!source.allowCovariantReturns())
  3156             // reject if there is a common method signature with
  3157             // incompatible return types.
  3158             chk.checkCompatibleAbstracts(warn.pos(), from, to);
  3159         return true;
  3162     private boolean sideCastFinal(Type from, Type to, Warner warn) {
  3163         // We are casting from type $from$ to type $to$, which are
  3164         // unrelated types one of which is final and the other of
  3165         // which is an interface.  This method
  3166         // tries to reject a cast by transferring type parameters
  3167         // from the final class to the interface.
  3168         boolean reverse = false;
  3169         Type target = to;
  3170         if ((to.tsym.flags() & INTERFACE) == 0) {
  3171             assert (from.tsym.flags() & INTERFACE) != 0;
  3172             reverse = true;
  3173             to = from;
  3174             from = target;
  3176         assert (from.tsym.flags() & FINAL) != 0;
  3177         Type t1 = asSuper(from, to.tsym);
  3178         if (t1 == null) return false;
  3179         Type t2 = to;
  3180         if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
  3181             return false;
  3182         if (!source.allowCovariantReturns())
  3183             // reject if there is a common method signature with
  3184             // incompatible return types.
  3185             chk.checkCompatibleAbstracts(warn.pos(), from, to);
  3186         if (!isReifiable(target) &&
  3187             (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2)))
  3188             warn.warnUnchecked();
  3189         return true;
  3192     private boolean giveWarning(Type from, Type to) {
  3193         // To and from are (possibly different) parameterizations
  3194         // of the same class or interface
  3195         return to.isParameterized() && !containsType(to.getTypeArguments(), from.getTypeArguments());
  3198     private List<Type> superClosure(Type t, Type s) {
  3199         List<Type> cl = List.nil();
  3200         for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
  3201             if (isSubtype(s, erasure(l.head))) {
  3202                 cl = insert(cl, l.head);
  3203             } else {
  3204                 cl = union(cl, superClosure(l.head, s));
  3207         return cl;
  3210     private boolean containsTypeEquivalent(Type t, Type s) {
  3211         return
  3212             isSameType(t, s) || // shortcut
  3213             containsType(t, s) && containsType(s, t);
  3216     /**
  3217      * Adapt a type by computing a substitution which maps a source
  3218      * type to a target type.
  3220      * @param source    the source type
  3221      * @param target    the target type
  3222      * @param from      the type variables of the computed substitution
  3223      * @param to        the types of the computed substitution.
  3224      */
  3225     public void adapt(Type source,
  3226                        Type target,
  3227                        ListBuffer<Type> from,
  3228                        ListBuffer<Type> to) throws AdaptFailure {
  3229         Map<Symbol,Type> mapping = new HashMap<Symbol,Type>();
  3230         adaptRecursive(source, target, from, to, mapping);
  3231         List<Type> fromList = from.toList();
  3232         List<Type> toList = to.toList();
  3233         while (!fromList.isEmpty()) {
  3234             Type val = mapping.get(fromList.head.tsym);
  3235             if (toList.head != val)
  3236                 toList.head = val;
  3237             fromList = fromList.tail;
  3238             toList = toList.tail;
  3241     // where
  3242         private void adaptRecursive(Type source,
  3243                                     Type target,
  3244                                     ListBuffer<Type> from,
  3245                                     ListBuffer<Type> to,
  3246                                     Map<Symbol,Type> mapping) throws AdaptFailure {
  3247             if (source.tag == TYPEVAR) {
  3248                 // Check to see if there is
  3249                 // already a mapping for $source$, in which case
  3250                 // the old mapping will be merged with the new
  3251                 Type val = mapping.get(source.tsym);
  3252                 if (val != null) {
  3253                     if (val.isSuperBound() && target.isSuperBound()) {
  3254                         val = isSubtype(lowerBound(val), lowerBound(target))
  3255                             ? target : val;
  3256                     } else if (val.isExtendsBound() && target.isExtendsBound()) {
  3257                         val = isSubtype(upperBound(val), upperBound(target))
  3258                             ? val : target;
  3259                     } else if (!isSameType(val, target)) {
  3260                         throw new AdaptFailure();
  3262                 } else {
  3263                     val = target;
  3264                     from.append(source);
  3265                     to.append(target);
  3267                 mapping.put(source.tsym, val);
  3268             } else if (source.tag == target.tag) {
  3269                 switch (source.tag) {
  3270                     case CLASS:
  3271                         adapt(source.allparams(), target.allparams(),
  3272                               from, to, mapping);
  3273                         break;
  3274                     case ARRAY:
  3275                         adaptRecursive(elemtype(source), elemtype(target),
  3276                                        from, to, mapping);
  3277                         break;
  3278                     case WILDCARD:
  3279                         if (source.isExtendsBound()) {
  3280                             adaptRecursive(upperBound(source), upperBound(target),
  3281                                            from, to, mapping);
  3282                         } else if (source.isSuperBound()) {
  3283                             adaptRecursive(lowerBound(source), lowerBound(target),
  3284                                            from, to, mapping);
  3286                         break;
  3290         public static class AdaptFailure extends Exception {
  3291             static final long serialVersionUID = -7490231548272701566L;
  3294     /**
  3295      * Adapt a type by computing a substitution which maps a list of
  3296      * source types to a list of target types.
  3298      * @param source    the source type
  3299      * @param target    the target type
  3300      * @param from      the type variables of the computed substitution
  3301      * @param to        the types of the computed substitution.
  3302      */
  3303     private void adapt(List<Type> source,
  3304                        List<Type> target,
  3305                        ListBuffer<Type> from,
  3306                        ListBuffer<Type> to,
  3307                        Map<Symbol,Type> mapping) throws AdaptFailure {
  3308         if (source.length() == target.length()) {
  3309             while (source.nonEmpty()) {
  3310                 adaptRecursive(source.head, target.head, from, to, mapping);
  3311                 source = source.tail;
  3312                 target = target.tail;
  3317     private void adaptSelf(Type t,
  3318                            ListBuffer<Type> from,
  3319                            ListBuffer<Type> to) {
  3320         try {
  3321             //if (t.tsym.type != t)
  3322                 adapt(t.tsym.type, t, from, to);
  3323         } catch (AdaptFailure ex) {
  3324             // Adapt should never fail calculating a mapping from
  3325             // t.tsym.type to t as there can be no merge problem.
  3326             throw new AssertionError(ex);
  3330     /**
  3331      * Rewrite all type variables (universal quantifiers) in the given
  3332      * type to wildcards (existential quantifiers).  This is used to
  3333      * determine if a cast is allowed.  For example, if high is true
  3334      * and {@code T <: Number}, then {@code List<T>} is rewritten to
  3335      * {@code List<?  extends Number>}.  Since {@code List<Integer> <:
  3336      * List<? extends Number>} a {@code List<T>} can be cast to {@code
  3337      * List<Integer>} with a warning.
  3338      * @param t a type
  3339      * @param high if true return an upper bound; otherwise a lower
  3340      * bound
  3341      * @param rewriteTypeVars only rewrite captured wildcards if false;
  3342      * otherwise rewrite all type variables
  3343      * @return the type rewritten with wildcards (existential
  3344      * quantifiers) only
  3345      */
  3346     private Type rewriteQuantifiers(Type t, boolean high, boolean rewriteTypeVars) {
  3347         ListBuffer<Type> from = new ListBuffer<Type>();
  3348         ListBuffer<Type> to = new ListBuffer<Type>();
  3349         adaptSelf(t, from, to);
  3350         ListBuffer<Type> rewritten = new ListBuffer<Type>();
  3351         List<Type> formals = from.toList();
  3352         boolean changed = false;
  3353         for (Type arg : to.toList()) {
  3354             Type bound;
  3355             if (rewriteTypeVars && arg.tag == TYPEVAR) {
  3356                 TypeVar tv = (TypeVar)arg;
  3357                 bound = high ? tv.bound : syms.botType;
  3358             } else {
  3359                 bound = high ? upperBound(arg) : lowerBound(arg);
  3361             Type newarg = bound;
  3362             if (arg != bound) {
  3363                 changed = true;
  3364                 newarg = high ? makeExtendsWildcard(bound, (TypeVar)formals.head)
  3365                               : makeSuperWildcard(bound, (TypeVar)formals.head);
  3367             rewritten.append(newarg);
  3368             formals = formals.tail;
  3370         if (changed)
  3371             return subst(t.tsym.type, from.toList(), rewritten.toList());
  3372         else
  3373             return t;
  3376     /**
  3377      * Create a wildcard with the given upper (extends) bound; create
  3378      * an unbounded wildcard if bound is Object.
  3380      * @param bound the upper bound
  3381      * @param formal the formal type parameter that will be
  3382      * substituted by the wildcard
  3383      */
  3384     private WildcardType makeExtendsWildcard(Type bound, TypeVar formal) {
  3385         if (bound == syms.objectType) {
  3386             return new WildcardType(syms.objectType,
  3387                                     BoundKind.UNBOUND,
  3388                                     syms.boundClass,
  3389                                     formal);
  3390         } else {
  3391             return new WildcardType(bound,
  3392                                     BoundKind.EXTENDS,
  3393                                     syms.boundClass,
  3394                                     formal);
  3398     /**
  3399      * Create a wildcard with the given lower (super) bound; create an
  3400      * unbounded wildcard if bound is bottom (type of {@code null}).
  3402      * @param bound the lower bound
  3403      * @param formal the formal type parameter that will be
  3404      * substituted by the wildcard
  3405      */
  3406     private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
  3407         if (bound.tag == BOT) {
  3408             return new WildcardType(syms.objectType,
  3409                                     BoundKind.UNBOUND,
  3410                                     syms.boundClass,
  3411                                     formal);
  3412         } else {
  3413             return new WildcardType(bound,
  3414                                     BoundKind.SUPER,
  3415                                     syms.boundClass,
  3416                                     formal);
  3420     /**
  3421      * A wrapper for a type that allows use in sets.
  3422      */
  3423     class SingletonType {
  3424         final Type t;
  3425         SingletonType(Type t) {
  3426             this.t = t;
  3428         public int hashCode() {
  3429             return Types.this.hashCode(t);
  3431         public boolean equals(Object obj) {
  3432             return (obj instanceof SingletonType) &&
  3433                 isSameType(t, ((SingletonType)obj).t);
  3435         public String toString() {
  3436             return t.toString();
  3439     // </editor-fold>
  3441     // <editor-fold defaultstate="collapsed" desc="Visitors">
  3442     /**
  3443      * A default visitor for types.  All visitor methods except
  3444      * visitType are implemented by delegating to visitType.  Concrete
  3445      * subclasses must provide an implementation of visitType and can
  3446      * override other methods as needed.
  3448      * @param <R> the return type of the operation implemented by this
  3449      * visitor; use Void if no return type is needed.
  3450      * @param <S> the type of the second argument (the first being the
  3451      * type itself) of the operation implemented by this visitor; use
  3452      * Void if a second argument is not needed.
  3453      */
  3454     public static abstract class DefaultTypeVisitor<R,S> implements Type.Visitor<R,S> {
  3455         final public R visit(Type t, S s)               { return t.accept(this, s); }
  3456         public R visitClassType(ClassType t, S s)       { return visitType(t, s); }
  3457         public R visitWildcardType(WildcardType t, S s) { return visitType(t, s); }
  3458         public R visitArrayType(ArrayType t, S s)       { return visitType(t, s); }
  3459         public R visitMethodType(MethodType t, S s)     { return visitType(t, s); }
  3460         public R visitPackageType(PackageType t, S s)   { return visitType(t, s); }
  3461         public R visitTypeVar(TypeVar t, S s)           { return visitType(t, s); }
  3462         public R visitCapturedType(CapturedType t, S s) { return visitType(t, s); }
  3463         public R visitForAll(ForAll t, S s)             { return visitType(t, s); }
  3464         public R visitUndetVar(UndetVar t, S s)         { return visitType(t, s); }
  3465         public R visitErrorType(ErrorType t, S s)       { return visitType(t, s); }
  3468     /**
  3469      * A default visitor for symbols.  All visitor methods except
  3470      * visitSymbol are implemented by delegating to visitSymbol.  Concrete
  3471      * subclasses must provide an implementation of visitSymbol and can
  3472      * override other methods as needed.
  3474      * @param <R> the return type of the operation implemented by this
  3475      * visitor; use Void if no return type is needed.
  3476      * @param <S> the type of the second argument (the first being the
  3477      * symbol itself) of the operation implemented by this visitor; use
  3478      * Void if a second argument is not needed.
  3479      */
  3480     public static abstract class DefaultSymbolVisitor<R,S> implements Symbol.Visitor<R,S> {
  3481         final public R visit(Symbol s, S arg)                   { return s.accept(this, arg); }
  3482         public R visitClassSymbol(ClassSymbol s, S arg)         { return visitSymbol(s, arg); }
  3483         public R visitMethodSymbol(MethodSymbol s, S arg)       { return visitSymbol(s, arg); }
  3484         public R visitOperatorSymbol(OperatorSymbol s, S arg)   { return visitSymbol(s, arg); }
  3485         public R visitPackageSymbol(PackageSymbol s, S arg)     { return visitSymbol(s, arg); }
  3486         public R visitTypeSymbol(TypeSymbol s, S arg)           { return visitSymbol(s, arg); }
  3487         public R visitVarSymbol(VarSymbol s, S arg)             { return visitSymbol(s, arg); }
  3490     /**
  3491      * A <em>simple</em> visitor for types.  This visitor is simple as
  3492      * captured wildcards, for-all types (generic methods), and
  3493      * undetermined type variables (part of inference) are hidden.
  3494      * Captured wildcards are hidden by treating them as type
  3495      * variables and the rest are hidden by visiting their qtypes.
  3497      * @param <R> the return type of the operation implemented by this
  3498      * visitor; use Void if no return type is needed.
  3499      * @param <S> the type of the second argument (the first being the
  3500      * type itself) of the operation implemented by this visitor; use
  3501      * Void if a second argument is not needed.
  3502      */
  3503     public static abstract class SimpleVisitor<R,S> extends DefaultTypeVisitor<R,S> {
  3504         @Override
  3505         public R visitCapturedType(CapturedType t, S s) {
  3506             return visitTypeVar(t, s);
  3508         @Override
  3509         public R visitForAll(ForAll t, S s) {
  3510             return visit(t.qtype, s);
  3512         @Override
  3513         public R visitUndetVar(UndetVar t, S s) {
  3514             return visit(t.qtype, s);
  3518     /**
  3519      * A plain relation on types.  That is a 2-ary function on the
  3520      * form Type&nbsp;&times;&nbsp;Type&nbsp;&rarr;&nbsp;Boolean.
  3521      * <!-- In plain text: Type x Type -> Boolean -->
  3522      */
  3523     public static abstract class TypeRelation extends SimpleVisitor<Boolean,Type> {}
  3525     /**
  3526      * A convenience visitor for implementing operations that only
  3527      * require one argument (the type itself), that is, unary
  3528      * operations.
  3530      * @param <R> the return type of the operation implemented by this
  3531      * visitor; use Void if no return type is needed.
  3532      */
  3533     public static abstract class UnaryVisitor<R> extends SimpleVisitor<R,Void> {
  3534         final public R visit(Type t) { return t.accept(this, null); }
  3537     /**
  3538      * A visitor for implementing a mapping from types to types.  The
  3539      * default behavior of this class is to implement the identity
  3540      * mapping (mapping a type to itself).  This can be overridden in
  3541      * subclasses.
  3543      * @param <S> the type of the second argument (the first being the
  3544      * type itself) of this mapping; use Void if a second argument is
  3545      * not needed.
  3546      */
  3547     public static class MapVisitor<S> extends DefaultTypeVisitor<Type,S> {
  3548         final public Type visit(Type t) { return t.accept(this, null); }
  3549         public Type visitType(Type t, S s) { return t; }
  3551     // </editor-fold>

mercurial