Save This Page
Home » openjdk-7 » com.sun.tools » javac » code » [javadoc | source]
    1   /*
    2    * Copyright (c) 2003, 2011, Oracle and/or its affiliates. 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.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package com.sun.tools.javac.code;
   27   
   28   import java.lang.ref.SoftReference;
   29   import java.util;
   30   
   31   import com.sun.tools.javac.util;
   32   import com.sun.tools.javac.util.List;
   33   
   34   import com.sun.tools.javac.jvm.ClassReader;
   35   import com.sun.tools.javac.code.Attribute.RetentionPolicy;
   36   import com.sun.tools.javac.code.Lint.LintCategory;
   37   import com.sun.tools.javac.comp.Check;
   38   
   39   import static com.sun.tools.javac.code.Scope.*;
   40   import static com.sun.tools.javac.code.Type.*;
   41   import static com.sun.tools.javac.code.TypeTags.*;
   42   import static com.sun.tools.javac.code.Symbol.*;
   43   import static com.sun.tools.javac.code.Flags.*;
   44   import static com.sun.tools.javac.code.BoundKind.*;
   45   import static com.sun.tools.javac.util.ListBuffer.lb;
   46   
   47   /**
   48    * Utility class containing various operations on types.
   49    *
   50    * <p>Unless other names are more illustrative, the following naming
   51    * conventions should be observed in this file:
   52    *
   53    * <dl>
   54    * <dt>t</dt>
   55    * <dd>If the first argument to an operation is a type, it should be named t.</dd>
   56    * <dt>s</dt>
   57    * <dd>Similarly, if the second argument to an operation is a type, it should be named s.</dd>
   58    * <dt>ts</dt>
   59    * <dd>If an operations takes a list of types, the first should be named ts.</dd>
   60    * <dt>ss</dt>
   61    * <dd>A second list of types should be named ss.</dd>
   62    * </dl>
   63    *
   64    * <p><b>This is NOT part of any supported API.
   65    * If you write code that depends on this, you do so at your own risk.
   66    * This code and its internal interfaces are subject to change or
   67    * deletion without notice.</b>
   68    */
   69   public class Types {
   70       protected static final Context.Key<Types> typesKey =
   71           new Context.Key<Types>();
   72   
   73       final Symtab syms;
   74       final JavacMessages messages;
   75       final Names names;
   76       final boolean allowBoxing;
   77       final boolean allowCovariantReturns;
   78       final boolean allowObjectToPrimitiveCast;
   79       final ClassReader reader;
   80       final Check chk;
   81       List<Warner> warnStack = List.nil();
   82       final Name capturedName;
   83   
   84       // <editor-fold defaultstate="collapsed" desc="Instantiating">
   85       public static Types instance(Context context) {
   86           Types instance = context.get(typesKey);
   87           if (instance == null)
   88               instance = new Types(context);
   89           return instance;
   90       }
   91   
   92       protected Types(Context context) {
   93           context.put(typesKey, this);
   94           syms = Symtab.instance(context);
   95           names = Names.instance(context);
   96           Source source = Source.instance(context);
   97           allowBoxing = source.allowBoxing();
   98           allowCovariantReturns = source.allowCovariantReturns();
   99           allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast();
  100           reader = ClassReader.instance(context);
  101           chk = Check.instance(context);
  102           capturedName = names.fromString("<captured wildcard>");
  103           messages = JavacMessages.instance(context);
  104       }
  105       // </editor-fold>
  106   
  107       // <editor-fold defaultstate="collapsed" desc="upperBound">
  108       /**
  109        * The "rvalue conversion".<br>
  110        * The upper bound of most types is the type
  111        * itself.  Wildcards, on the other hand have upper
  112        * and lower bounds.
  113        * @param t a type
  114        * @return the upper bound of the given type
  115        */
  116       public Type upperBound(Type t) {
  117           return upperBound.visit(t);
  118       }
  119       // where
  120           private final MapVisitor<Void> upperBound = new MapVisitor<Void>() {
  121   
  122               @Override
  123               public Type visitWildcardType(WildcardType t, Void ignored) {
  124                   if (t.isSuperBound())
  125                       return t.bound == null ? syms.objectType : t.bound.bound;
  126                   else
  127                       return visit(t.type);
  128               }
  129   
  130               @Override
  131               public Type visitCapturedType(CapturedType t, Void ignored) {
  132                   return visit(t.bound);
  133               }
  134           };
  135       // </editor-fold>
  136   
  137       // <editor-fold defaultstate="collapsed" desc="lowerBound">
  138       /**
  139        * The "lvalue conversion".<br>
  140        * The lower bound of most types is the type
  141        * itself.  Wildcards, on the other hand have upper
  142        * and lower bounds.
  143        * @param t a type
  144        * @return the lower bound of the given type
  145        */
  146       public Type lowerBound(Type t) {
  147           return lowerBound.visit(t);
  148       }
  149       // where
  150           private final MapVisitor<Void> lowerBound = new MapVisitor<Void>() {
  151   
  152               @Override
  153               public Type visitWildcardType(WildcardType t, Void ignored) {
  154                   return t.isExtendsBound() ? syms.botType : visit(t.type);
  155               }
  156   
  157               @Override
  158               public Type visitCapturedType(CapturedType t, Void ignored) {
  159                   return visit(t.getLowerBound());
  160               }
  161           };
  162       // </editor-fold>
  163   
  164       // <editor-fold defaultstate="collapsed" desc="isUnbounded">
  165       /**
  166        * Checks that all the arguments to a class are unbounded
  167        * wildcards or something else that doesn't make any restrictions
  168        * on the arguments. If a class isUnbounded, a raw super- or
  169        * subclass can be cast to it without a warning.
  170        * @param t a type
  171        * @return true iff the given type is unbounded or raw
  172        */
  173       public boolean isUnbounded(Type t) {
  174           return isUnbounded.visit(t);
  175       }
  176       // where
  177           private final UnaryVisitor<Boolean> isUnbounded = new UnaryVisitor<Boolean>() {
  178   
  179               public Boolean visitType(Type t, Void ignored) {
  180                   return true;
  181               }
  182   
  183               @Override
  184               public Boolean visitClassType(ClassType t, Void ignored) {
  185                   List<Type> parms = t.tsym.type.allparams();
  186                   List<Type> args = t.allparams();
  187                   while (parms.nonEmpty()) {
  188                       WildcardType unb = new WildcardType(syms.objectType,
  189                                                           BoundKind.UNBOUND,
  190                                                           syms.boundClass,
  191                                                           (TypeVar)parms.head);
  192                       if (!containsType(args.head, unb))
  193                           return false;
  194                       parms = parms.tail;
  195                       args = args.tail;
  196                   }
  197                   return true;
  198               }
  199           };
  200       // </editor-fold>
  201   
  202       // <editor-fold defaultstate="collapsed" desc="asSub">
  203       /**
  204        * Return the least specific subtype of t that starts with symbol
  205        * sym.  If none exists, return null.  The least specific subtype
  206        * is determined as follows:
  207        *
  208        * <p>If there is exactly one parameterized instance of sym that is a
  209        * subtype of t, that parameterized instance is returned.<br>
  210        * Otherwise, if the plain type or raw type `sym' is a subtype of
  211        * type t, the type `sym' itself is returned.  Otherwise, null is
  212        * returned.
  213        */
  214       public Type asSub(Type t, Symbol sym) {
  215           return asSub.visit(t, sym);
  216       }
  217       // where
  218           private final SimpleVisitor<Type,Symbol> asSub = new SimpleVisitor<Type,Symbol>() {
  219   
  220               public Type visitType(Type t, Symbol sym) {
  221                   return null;
  222               }
  223   
  224               @Override
  225               public Type visitClassType(ClassType t, Symbol sym) {
  226                   if (t.tsym == sym)
  227                       return t;
  228                   Type base = asSuper(sym.type, t.tsym);
  229                   if (base == null)
  230                       return null;
  231                   ListBuffer<Type> from = new ListBuffer<Type>();
  232                   ListBuffer<Type> to = new ListBuffer<Type>();
  233                   try {
  234                       adapt(base, t, from, to);
  235                   } catch (AdaptFailure ex) {
  236                       return null;
  237                   }
  238                   Type res = subst(sym.type, from.toList(), to.toList());
  239                   if (!isSubtype(res, t))
  240                       return null;
  241                   ListBuffer<Type> openVars = new ListBuffer<Type>();
  242                   for (List<Type> l = sym.type.allparams();
  243                        l.nonEmpty(); l = l.tail)
  244                       if (res.contains(l.head) && !t.contains(l.head))
  245                           openVars.append(l.head);
  246                   if (openVars.nonEmpty()) {
  247                       if (t.isRaw()) {
  248                           // The subtype of a raw type is raw
  249                           res = erasure(res);
  250                       } else {
  251                           // Unbound type arguments default to ?
  252                           List<Type> opens = openVars.toList();
  253                           ListBuffer<Type> qs = new ListBuffer<Type>();
  254                           for (List<Type> iter = opens; iter.nonEmpty(); iter = iter.tail) {
  255                               qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head));
  256                           }
  257                           res = subst(res, opens, qs.toList());
  258                       }
  259                   }
  260                   return res;
  261               }
  262   
  263               @Override
  264               public Type visitErrorType(ErrorType t, Symbol sym) {
  265                   return t;
  266               }
  267           };
  268       // </editor-fold>
  269   
  270       // <editor-fold defaultstate="collapsed" desc="isConvertible">
  271       /**
  272        * Is t a subtype of or convertiable via boxing/unboxing
  273        * convertions to s?
  274        */
  275       public boolean isConvertible(Type t, Type s, Warner warn) {
  276           boolean tPrimitive = t.isPrimitive();
  277           boolean sPrimitive = s.isPrimitive();
  278           if (tPrimitive == sPrimitive) {
  279               checkUnsafeVarargsConversion(t, s, warn);
  280               return isSubtypeUnchecked(t, s, warn);
  281           }
  282           if (!allowBoxing) return false;
  283           return tPrimitive
  284               ? isSubtype(boxedClass(t).type, s)
  285               : isSubtype(unboxedType(t), s);
  286       }
  287       //where
  288       private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) {
  289           if (t.tag != ARRAY || isReifiable(t)) return;
  290           ArrayType from = (ArrayType)t;
  291           boolean shouldWarn = false;
  292           switch (s.tag) {
  293               case ARRAY:
  294                   ArrayType to = (ArrayType)s;
  295                   shouldWarn = from.isVarargs() &&
  296                           !to.isVarargs() &&
  297                           !isReifiable(from);
  298                   break;
  299               case CLASS:
  300                   shouldWarn = from.isVarargs() &&
  301                           isSubtype(from, s);
  302                   break;
  303           }
  304           if (shouldWarn) {
  305               warn.warn(LintCategory.VARARGS);
  306           }
  307       }
  308   
  309       /**
  310        * Is t a subtype of or convertiable via boxing/unboxing
  311        * convertions to s?
  312        */
  313       public boolean isConvertible(Type t, Type s) {
  314           return isConvertible(t, s, Warner.noWarnings);
  315       }
  316       // </editor-fold>
  317   
  318       // <editor-fold defaultstate="collapsed" desc="isSubtype">
  319       /**
  320        * Is t an unchecked subtype of s?
  321        */
  322       public boolean isSubtypeUnchecked(Type t, Type s) {
  323           return isSubtypeUnchecked(t, s, Warner.noWarnings);
  324       }
  325       /**
  326        * Is t an unchecked subtype of s?
  327        */
  328       public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) {
  329           if (t.tag == ARRAY && s.tag == ARRAY) {
  330               if (((ArrayType)t).elemtype.tag <= lastBaseTag) {
  331                   return isSameType(elemtype(t), elemtype(s));
  332               } else {
  333                   ArrayType from = (ArrayType)t;
  334                   ArrayType to = (ArrayType)s;
  335                   if (from.isVarargs() &&
  336                           !to.isVarargs() &&
  337                           !isReifiable(from)) {
  338                       warn.warn(LintCategory.VARARGS);
  339                   }
  340                   return isSubtypeUnchecked(elemtype(t), elemtype(s), warn);
  341               }
  342           } else if (isSubtype(t, s)) {
  343               return true;
  344           }
  345           else if (t.tag == TYPEVAR) {
  346               return isSubtypeUnchecked(t.getUpperBound(), s, warn);
  347           }
  348           else if (s.tag == UNDETVAR) {
  349               UndetVar uv = (UndetVar)s;
  350               if (uv.inst != null)
  351                   return isSubtypeUnchecked(t, uv.inst, warn);
  352           }
  353           else if (!s.isRaw()) {
  354               Type t2 = asSuper(t, s.tsym);
  355               if (t2 != null && t2.isRaw()) {
  356                   if (isReifiable(s))
  357                       warn.silentWarn(LintCategory.UNCHECKED);
  358                   else
  359                       warn.warn(LintCategory.UNCHECKED);
  360                   return true;
  361               }
  362           }
  363           return false;
  364       }
  365   
  366       /**
  367        * Is t a subtype of s?<br>
  368        * (not defined for Method and ForAll types)
  369        */
  370       final public boolean isSubtype(Type t, Type s) {
  371           return isSubtype(t, s, true);
  372       }
  373       final public boolean isSubtypeNoCapture(Type t, Type s) {
  374           return isSubtype(t, s, false);
  375       }
  376       public boolean isSubtype(Type t, Type s, boolean capture) {
  377           if (t == s)
  378               return true;
  379   
  380           if (s.tag >= firstPartialTag)
  381               return isSuperType(s, t);
  382   
  383           if (s.isCompound()) {
  384               for (Type s2 : interfaces(s).prepend(supertype(s))) {
  385                   if (!isSubtype(t, s2, capture))
  386                       return false;
  387               }
  388               return true;
  389           }
  390   
  391           Type lower = lowerBound(s);
  392           if (s != lower)
  393               return isSubtype(capture ? capture(t) : t, lower, false);
  394   
  395           return isSubtype.visit(capture ? capture(t) : t, s);
  396       }
  397       // where
  398           private TypeRelation isSubtype = new TypeRelation()
  399           {
  400               public Boolean visitType(Type t, Type s) {
  401                   switch (t.tag) {
  402                   case BYTE: case CHAR:
  403                       return (t.tag == s.tag ||
  404                                 t.tag + 2 <= s.tag && s.tag <= DOUBLE);
  405                   case SHORT: case INT: case LONG: case FLOAT: case DOUBLE:
  406                       return t.tag <= s.tag && s.tag <= DOUBLE;
  407                   case BOOLEAN: case VOID:
  408                       return t.tag == s.tag;
  409                   case TYPEVAR:
  410                       return isSubtypeNoCapture(t.getUpperBound(), s);
  411                   case BOT:
  412                       return
  413                           s.tag == BOT || s.tag == CLASS ||
  414                           s.tag == ARRAY || s.tag == TYPEVAR;
  415                   case WILDCARD: //we shouldn't be here - avoids crash (see 7034495)
  416                   case NONE:
  417                       return false;
  418                   default:
  419                       throw new AssertionError("isSubtype " + t.tag);
  420                   }
  421               }
  422   
  423               private Set<TypePair> cache = new HashSet<TypePair>();
  424   
  425               private boolean containsTypeRecursive(Type t, Type s) {
  426                   TypePair pair = new TypePair(t, s);
  427                   if (cache.add(pair)) {
  428                       try {
  429                           return containsType(t.getTypeArguments(),
  430                                               s.getTypeArguments());
  431                       } finally {
  432                           cache.remove(pair);
  433                       }
  434                   } else {
  435                       return containsType(t.getTypeArguments(),
  436                                           rewriteSupers(s).getTypeArguments());
  437                   }
  438               }
  439   
  440               private Type rewriteSupers(Type t) {
  441                   if (!t.isParameterized())
  442                       return t;
  443                   ListBuffer<Type> from = lb();
  444                   ListBuffer<Type> to = lb();
  445                   adaptSelf(t, from, to);
  446                   if (from.isEmpty())
  447                       return t;
  448                   ListBuffer<Type> rewrite = lb();
  449                   boolean changed = false;
  450                   for (Type orig : to.toList()) {
  451                       Type s = rewriteSupers(orig);
  452                       if (s.isSuperBound() && !s.isExtendsBound()) {
  453                           s = new WildcardType(syms.objectType,
  454                                                BoundKind.UNBOUND,
  455                                                syms.boundClass);
  456                           changed = true;
  457                       } else if (s != orig) {
  458                           s = new WildcardType(upperBound(s),
  459                                                BoundKind.EXTENDS,
  460                                                syms.boundClass);
  461                           changed = true;
  462                       }
  463                       rewrite.append(s);
  464                   }
  465                   if (changed)
  466                       return subst(t.tsym.type, from.toList(), rewrite.toList());
  467                   else
  468                       return t;
  469               }
  470   
  471               @Override
  472               public Boolean visitClassType(ClassType t, Type s) {
  473                   Type sup = asSuper(t, s.tsym);
  474                   return sup != null
  475                       && sup.tsym == s.tsym
  476                       // You're not allowed to write
  477                       //     Vector<Object> vec = new Vector<String>();
  478                       // But with wildcards you can write
  479                       //     Vector<? extends Object> vec = new Vector<String>();
  480                       // which means that subtype checking must be done
  481                       // here instead of same-type checking (via containsType).
  482                       && (!s.isParameterized() || containsTypeRecursive(s, sup))
  483                       && isSubtypeNoCapture(sup.getEnclosingType(),
  484                                             s.getEnclosingType());
  485               }
  486   
  487               @Override
  488               public Boolean visitArrayType(ArrayType t, Type s) {
  489                   if (s.tag == ARRAY) {
  490                       if (t.elemtype.tag <= lastBaseTag)
  491                           return isSameType(t.elemtype, elemtype(s));
  492                       else
  493                           return isSubtypeNoCapture(t.elemtype, elemtype(s));
  494                   }
  495   
  496                   if (s.tag == CLASS) {
  497                       Name sname = s.tsym.getQualifiedName();
  498                       return sname == names.java_lang_Object
  499                           || sname == names.java_lang_Cloneable
  500                           || sname == names.java_io_Serializable;
  501                   }
  502   
  503                   return false;
  504               }
  505   
  506               @Override
  507               public Boolean visitUndetVar(UndetVar t, Type s) {
  508                   //todo: test against origin needed? or replace with substitution?
  509                   if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN)
  510                       return true;
  511   
  512                   if (t.inst != null)
  513                       return isSubtypeNoCapture(t.inst, s); // TODO: ", warn"?
  514   
  515                   t.hibounds = t.hibounds.prepend(s);
  516                   return true;
  517               }
  518   
  519               @Override
  520               public Boolean visitErrorType(ErrorType t, Type s) {
  521                   return true;
  522               }
  523           };
  524   
  525       /**
  526        * Is t a subtype of every type in given list `ts'?<br>
  527        * (not defined for Method and ForAll types)<br>
  528        * Allows unchecked conversions.
  529        */
  530       public boolean isSubtypeUnchecked(Type t, List<Type> ts, Warner warn) {
  531           for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
  532               if (!isSubtypeUnchecked(t, l.head, warn))
  533                   return false;
  534           return true;
  535       }
  536   
  537       /**
  538        * Are corresponding elements of ts subtypes of ss?  If lists are
  539        * of different length, return false.
  540        */
  541       public boolean isSubtypes(List<Type> ts, List<Type> ss) {
  542           while (ts.tail != null && ss.tail != null
  543                  /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
  544                  isSubtype(ts.head, ss.head)) {
  545               ts = ts.tail;
  546               ss = ss.tail;
  547           }
  548           return ts.tail == null && ss.tail == null;
  549           /*inlined: ts.isEmpty() && ss.isEmpty();*/
  550       }
  551   
  552       /**
  553        * Are corresponding elements of ts subtypes of ss, allowing
  554        * unchecked conversions?  If lists are of different length,
  555        * return false.
  556        **/
  557       public boolean isSubtypesUnchecked(List<Type> ts, List<Type> ss, Warner warn) {
  558           while (ts.tail != null && ss.tail != null
  559                  /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
  560                  isSubtypeUnchecked(ts.head, ss.head, warn)) {
  561               ts = ts.tail;
  562               ss = ss.tail;
  563           }
  564           return ts.tail == null && ss.tail == null;
  565           /*inlined: ts.isEmpty() && ss.isEmpty();*/
  566       }
  567       // </editor-fold>
  568   
  569       // <editor-fold defaultstate="collapsed" desc="isSuperType">
  570       /**
  571        * Is t a supertype of s?
  572        */
  573       public boolean isSuperType(Type t, Type s) {
  574           switch (t.tag) {
  575           case ERROR:
  576               return true;
  577           case UNDETVAR: {
  578               UndetVar undet = (UndetVar)t;
  579               if (t == s ||
  580                   undet.qtype == s ||
  581                   s.tag == ERROR ||
  582                   s.tag == BOT) return true;
  583               if (undet.inst != null)
  584                   return isSubtype(s, undet.inst);
  585               undet.lobounds = undet.lobounds.prepend(s);
  586               return true;
  587           }
  588           default:
  589               return isSubtype(s, t);
  590           }
  591       }
  592       // </editor-fold>
  593   
  594       // <editor-fold defaultstate="collapsed" desc="isSameType">
  595       /**
  596        * Are corresponding elements of the lists the same type?  If
  597        * lists are of different length, return false.
  598        */
  599       public boolean isSameTypes(List<Type> ts, List<Type> ss) {
  600           while (ts.tail != null && ss.tail != null
  601                  /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
  602                  isSameType(ts.head, ss.head)) {
  603               ts = ts.tail;
  604               ss = ss.tail;
  605           }
  606           return ts.tail == null && ss.tail == null;
  607           /*inlined: ts.isEmpty() && ss.isEmpty();*/
  608       }
  609   
  610       /**
  611        * Is t the same type as s?
  612        */
  613       public boolean isSameType(Type t, Type s) {
  614           return isSameType.visit(t, s);
  615       }
  616       // where
  617           private TypeRelation isSameType = new TypeRelation() {
  618   
  619               public Boolean visitType(Type t, Type s) {
  620                   if (t == s)
  621                       return true;
  622   
  623                   if (s.tag >= firstPartialTag)
  624                       return visit(s, t);
  625   
  626                   switch (t.tag) {
  627                   case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
  628                   case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE:
  629                       return t.tag == s.tag;
  630                   case TYPEVAR: {
  631                       if (s.tag == TYPEVAR) {
  632                           //type-substitution does not preserve type-var types
  633                           //check that type var symbols and bounds are indeed the same
  634                           return t.tsym == s.tsym &&
  635                                   visit(t.getUpperBound(), s.getUpperBound());
  636                       }
  637                       else {
  638                           //special case for s == ? super X, where upper(s) = u
  639                           //check that u == t, where u has been set by Type.withTypeVar
  640                           return s.isSuperBound() &&
  641                                   !s.isExtendsBound() &&
  642                                   visit(t, upperBound(s));
  643                       }
  644                   }
  645                   default:
  646                       throw new AssertionError("isSameType " + t.tag);
  647                   }
  648               }
  649   
  650               @Override
  651               public Boolean visitWildcardType(WildcardType t, Type s) {
  652                   if (s.tag >= firstPartialTag)
  653                       return visit(s, t);
  654                   else
  655                       return false;
  656               }
  657   
  658               @Override
  659               public Boolean visitClassType(ClassType t, Type s) {
  660                   if (t == s)
  661                       return true;
  662   
  663                   if (s.tag >= firstPartialTag)
  664                       return visit(s, t);
  665   
  666                   if (s.isSuperBound() && !s.isExtendsBound())
  667                       return visit(t, upperBound(s)) && visit(t, lowerBound(s));
  668   
  669                   if (t.isCompound() && s.isCompound()) {
  670                       if (!visit(supertype(t), supertype(s)))
  671                           return false;
  672   
  673                       HashSet<SingletonType> set = new HashSet<SingletonType>();
  674                       for (Type x : interfaces(t))
  675                           set.add(new SingletonType(x));
  676                       for (Type x : interfaces(s)) {
  677                           if (!set.remove(new SingletonType(x)))
  678                               return false;
  679                       }
  680                       return (set.isEmpty());
  681                   }
  682                   return t.tsym == s.tsym
  683                       && visit(t.getEnclosingType(), s.getEnclosingType())
  684                       && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments());
  685               }
  686   
  687               @Override
  688               public Boolean visitArrayType(ArrayType t, Type s) {
  689                   if (t == s)
  690                       return true;
  691   
  692                   if (s.tag >= firstPartialTag)
  693                       return visit(s, t);
  694   
  695                   return s.tag == ARRAY
  696                       && containsTypeEquivalent(t.elemtype, elemtype(s));
  697               }
  698   
  699               @Override
  700               public Boolean visitMethodType(MethodType t, Type s) {
  701                   // isSameType for methods does not take thrown
  702                   // exceptions into account!
  703                   return hasSameArgs(t, s) && visit(t.getReturnType(), s.getReturnType());
  704               }
  705   
  706               @Override
  707               public Boolean visitPackageType(PackageType t, Type s) {
  708                   return t == s;
  709               }
  710   
  711               @Override
  712               public Boolean visitForAll(ForAll t, Type s) {
  713                   if (s.tag != FORALL)
  714                       return false;
  715   
  716                   ForAll forAll = (ForAll)s;
  717                   return hasSameBounds(t, forAll)
  718                       && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
  719               }
  720   
  721               @Override
  722               public Boolean visitUndetVar(UndetVar t, Type s) {
  723                   if (s.tag == WILDCARD)
  724                       // FIXME, this might be leftovers from before capture conversion
  725                       return false;
  726   
  727                   if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN)
  728                       return true;
  729   
  730                   if (t.inst != null)
  731                       return visit(t.inst, s);
  732   
  733                   t.inst = fromUnknownFun.apply(s);
  734                   for (List<Type> l = t.lobounds; l.nonEmpty(); l = l.tail) {
  735                       if (!isSubtype(l.head, t.inst))
  736                           return false;
  737                   }
  738                   for (List<Type> l = t.hibounds; l.nonEmpty(); l = l.tail) {
  739                       if (!isSubtype(t.inst, l.head))
  740                           return false;
  741                   }
  742                   return true;
  743               }
  744   
  745               @Override
  746               public Boolean visitErrorType(ErrorType t, Type s) {
  747                   return true;
  748               }
  749           };
  750       // </editor-fold>
  751   
  752       // <editor-fold defaultstate="collapsed" desc="fromUnknownFun">
  753       /**
  754        * A mapping that turns all unknown types in this type to fresh
  755        * unknown variables.
  756        */
  757       public Mapping fromUnknownFun = new Mapping("fromUnknownFun") {
  758               public Type apply(Type t) {
  759                   if (t.tag == UNKNOWN) return new UndetVar(t);
  760                   else return t.map(this);
  761               }
  762           };
  763       // </editor-fold>
  764   
  765       // <editor-fold defaultstate="collapsed" desc="Contains Type">
  766       public boolean containedBy(Type t, Type s) {
  767           switch (t.tag) {
  768           case UNDETVAR:
  769               if (s.tag == WILDCARD) {
  770                   UndetVar undetvar = (UndetVar)t;
  771                   WildcardType wt = (WildcardType)s;
  772                   switch(wt.kind) {
  773                       case UNBOUND: //similar to ? extends Object
  774                       case EXTENDS: {
  775                           Type bound = upperBound(s);
  776                           // We should check the new upper bound against any of the
  777                           // undetvar's lower bounds.
  778                           for (Type t2 : undetvar.lobounds) {
  779                               if (!isSubtype(t2, bound))
  780                                   return false;
  781                           }
  782                           undetvar.hibounds = undetvar.hibounds.prepend(bound);
  783                           break;
  784                       }
  785                       case SUPER: {
  786                           Type bound = lowerBound(s);
  787                           // We should check the new lower bound against any of the
  788                           // undetvar's lower bounds.
  789                           for (Type t2 : undetvar.hibounds) {
  790                               if (!isSubtype(bound, t2))
  791                                   return false;
  792                           }
  793                           undetvar.lobounds = undetvar.lobounds.prepend(bound);
  794                           break;
  795                       }
  796                   }
  797                   return true;
  798               } else {
  799                   return isSameType(t, s);
  800               }
  801           case ERROR:
  802               return true;
  803           default:
  804               return containsType(s, t);
  805           }
  806       }
  807   
  808       boolean containsType(List<Type> ts, List<Type> ss) {
  809           while (ts.nonEmpty() && ss.nonEmpty()
  810                  && containsType(ts.head, ss.head)) {
  811               ts = ts.tail;
  812               ss = ss.tail;
  813           }
  814           return ts.isEmpty() && ss.isEmpty();
  815       }
  816   
  817       /**
  818        * Check if t contains s.
  819        *
  820        * <p>T contains S if:
  821        *
  822        * <p>{@code L(T) <: L(S) && U(S) <: U(T)}
  823        *
  824        * <p>This relation is only used by ClassType.isSubtype(), that
  825        * is,
  826        *
  827        * <p>{@code C<S> <: C<T> if T contains S.}
  828        *
  829        * <p>Because of F-bounds, this relation can lead to infinite
  830        * recursion.  Thus we must somehow break that recursion.  Notice
  831        * that containsType() is only called from ClassType.isSubtype().
  832        * Since the arguments have already been checked against their
  833        * bounds, we know:
  834        *
  835        * <p>{@code U(S) <: U(T) if T is "super" bound (U(T) *is* the bound)}
  836        *
  837        * <p>{@code L(T) <: L(S) if T is "extends" bound (L(T) is bottom)}
  838        *
  839        * @param t a type
  840        * @param s a type
  841        */
  842       public boolean containsType(Type t, Type s) {
  843           return containsType.visit(t, s);
  844       }
  845       // where
  846           private TypeRelation containsType = new TypeRelation() {
  847   
  848               private Type U(Type t) {
  849                   while (t.tag == WILDCARD) {
  850                       WildcardType w = (WildcardType)t;
  851                       if (w.isSuperBound())
  852                           return w.bound == null ? syms.objectType : w.bound.bound;
  853                       else
  854                           t = w.type;
  855                   }
  856                   return t;
  857               }
  858   
  859               private Type L(Type t) {
  860                   while (t.tag == WILDCARD) {
  861                       WildcardType w = (WildcardType)t;
  862                       if (w.isExtendsBound())
  863                           return syms.botType;
  864                       else
  865                           t = w.type;
  866                   }
  867                   return t;
  868               }
  869   
  870               public Boolean visitType(Type t, Type s) {
  871                   if (s.tag >= firstPartialTag)
  872                       return containedBy(s, t);
  873                   else
  874                       return isSameType(t, s);
  875               }
  876   
  877   //            void debugContainsType(WildcardType t, Type s) {
  878   //                System.err.println();
  879   //                System.err.format(" does %s contain %s?%n", t, s);
  880   //                System.err.format(" %s U(%s) <: U(%s) %s = %s%n",
  881   //                                  upperBound(s), s, t, U(t),
  882   //                                  t.isSuperBound()
  883   //                                  || isSubtypeNoCapture(upperBound(s), U(t)));
  884   //                System.err.format(" %s L(%s) <: L(%s) %s = %s%n",
  885   //                                  L(t), t, s, lowerBound(s),
  886   //                                  t.isExtendsBound()
  887   //                                  || isSubtypeNoCapture(L(t), lowerBound(s)));
  888   //                System.err.println();
  889   //            }
  890   
  891               @Override
  892               public Boolean visitWildcardType(WildcardType t, Type s) {
  893                   if (s.tag >= firstPartialTag)
  894                       return containedBy(s, t);
  895                   else {
  896   //                    debugContainsType(t, s);
  897                       return isSameWildcard(t, s)
  898                           || isCaptureOf(s, t)
  899                           || ((t.isExtendsBound() || isSubtypeNoCapture(L(t), lowerBound(s))) &&
  900                               (t.isSuperBound() || isSubtypeNoCapture(upperBound(s), U(t))));
  901                   }
  902               }
  903   
  904               @Override
  905               public Boolean visitUndetVar(UndetVar t, Type s) {
  906                   if (s.tag != WILDCARD)
  907                       return isSameType(t, s);
  908                   else
  909                       return false;
  910               }
  911   
  912               @Override
  913               public Boolean visitErrorType(ErrorType t, Type s) {
  914                   return true;
  915               }
  916           };
  917   
  918       public boolean isCaptureOf(Type s, WildcardType t) {
  919           if (s.tag != TYPEVAR || !((TypeVar)s).isCaptured())
  920               return false;
  921           return isSameWildcard(t, ((CapturedType)s).wildcard);
  922       }
  923   
  924       public boolean isSameWildcard(WildcardType t, Type s) {
  925           if (s.tag != WILDCARD)
  926               return false;
  927           WildcardType w = (WildcardType)s;
  928           return w.kind == t.kind && w.type == t.type;
  929       }
  930   
  931       public boolean containsTypeEquivalent(List<Type> ts, List<Type> ss) {
  932           while (ts.nonEmpty() && ss.nonEmpty()
  933                  && containsTypeEquivalent(ts.head, ss.head)) {
  934               ts = ts.tail;
  935               ss = ss.tail;
  936           }
  937           return ts.isEmpty() && ss.isEmpty();
  938       }
  939       // </editor-fold>
  940   
  941       // <editor-fold defaultstate="collapsed" desc="isCastable">
  942       public boolean isCastable(Type t, Type s) {
  943           return isCastable(t, s, Warner.noWarnings);
  944       }
  945   
  946       /**
  947        * Is t is castable to s?<br>
  948        * s is assumed to be an erased type.<br>
  949        * (not defined for Method and ForAll types).
  950        */
  951       public boolean isCastable(Type t, Type s, Warner warn) {
  952           if (t == s)
  953               return true;
  954   
  955           if (t.isPrimitive() != s.isPrimitive())
  956               return allowBoxing && (
  957                       isConvertible(t, s, warn)
  958                       || (allowObjectToPrimitiveCast &&
  959                           s.isPrimitive() &&
  960                           isSubtype(boxedClass(s).type, t)));
  961           if (warn != warnStack.head) {
  962               try {
  963                   warnStack = warnStack.prepend(warn);
  964                   checkUnsafeVarargsConversion(t, s, warn);
  965                   return isCastable.visit(t,s);
  966               } finally {
  967                   warnStack = warnStack.tail;
  968               }
  969           } else {
  970               return isCastable.visit(t,s);
  971           }
  972       }
  973       // where
  974           private TypeRelation isCastable = new TypeRelation() {
  975   
  976               public Boolean visitType(Type t, Type s) {
  977                   if (s.tag == ERROR)
  978                       return true;
  979   
  980                   switch (t.tag) {
  981                   case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
  982                   case DOUBLE:
  983                       return s.tag <= DOUBLE;
  984                   case BOOLEAN:
  985                       return s.tag == BOOLEAN;
  986                   case VOID:
  987                       return false;
  988                   case BOT:
  989                       return isSubtype(t, s);
  990                   default:
  991                       throw new AssertionError();
  992                   }
  993               }
  994   
  995               @Override
  996               public Boolean visitWildcardType(WildcardType t, Type s) {
  997                   return isCastable(upperBound(t), s, warnStack.head);
  998               }
  999   
 1000               @Override
 1001               public Boolean visitClassType(ClassType t, Type s) {
 1002                   if (s.tag == ERROR || s.tag == BOT)
 1003                       return true;
 1004   
 1005                   if (s.tag == TYPEVAR) {
 1006                       if (isCastable(t, s.getUpperBound(), Warner.noWarnings)) {
 1007                           warnStack.head.warn(LintCategory.UNCHECKED);
 1008                           return true;
 1009                       } else {
 1010                           return false;
 1011                       }
 1012                   }
 1013   
 1014                   if (t.isCompound()) {
 1015                       Warner oldWarner = warnStack.head;
 1016                       warnStack.head = Warner.noWarnings;
 1017                       if (!visit(supertype(t), s))
 1018                           return false;
 1019                       for (Type intf : interfaces(t)) {
 1020                           if (!visit(intf, s))
 1021                               return false;
 1022                       }
 1023                       if (warnStack.head.hasLint(LintCategory.UNCHECKED))
 1024                           oldWarner.warn(LintCategory.UNCHECKED);
 1025                       return true;
 1026                   }
 1027   
 1028                   if (s.isCompound()) {
 1029                       // call recursively to reuse the above code
 1030                       return visitClassType((ClassType)s, t);
 1031                   }
 1032   
 1033                   if (s.tag == CLASS || s.tag == ARRAY) {
 1034                       boolean upcast;
 1035                       if ((upcast = isSubtype(erasure(t), erasure(s)))
 1036                           || isSubtype(erasure(s), erasure(t))) {
 1037                           if (!upcast && s.tag == ARRAY) {
 1038                               if (!isReifiable(s))
 1039                                   warnStack.head.warn(LintCategory.UNCHECKED);
 1040                               return true;
 1041                           } else if (s.isRaw()) {
 1042                               return true;
 1043                           } else if (t.isRaw()) {
 1044                               if (!isUnbounded(s))
 1045                                   warnStack.head.warn(LintCategory.UNCHECKED);
 1046                               return true;
 1047                           }
 1048                           // Assume |a| <: |b|
 1049                           final Type a = upcast ? t : s;
 1050                           final Type b = upcast ? s : t;
 1051                           final boolean HIGH = true;
 1052                           final boolean LOW = false;
 1053                           final boolean DONT_REWRITE_TYPEVARS = false;
 1054                           Type aHigh = rewriteQuantifiers(a, HIGH, DONT_REWRITE_TYPEVARS);
 1055                           Type aLow  = rewriteQuantifiers(a, LOW,  DONT_REWRITE_TYPEVARS);
 1056                           Type bHigh = rewriteQuantifiers(b, HIGH, DONT_REWRITE_TYPEVARS);
 1057                           Type bLow  = rewriteQuantifiers(b, LOW,  DONT_REWRITE_TYPEVARS);
 1058                           Type lowSub = asSub(bLow, aLow.tsym);
 1059                           Type highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym);
 1060                           if (highSub == null) {
 1061                               final boolean REWRITE_TYPEVARS = true;
 1062                               aHigh = rewriteQuantifiers(a, HIGH, REWRITE_TYPEVARS);
 1063                               aLow  = rewriteQuantifiers(a, LOW,  REWRITE_TYPEVARS);
 1064                               bHigh = rewriteQuantifiers(b, HIGH, REWRITE_TYPEVARS);
 1065                               bLow  = rewriteQuantifiers(b, LOW,  REWRITE_TYPEVARS);
 1066                               lowSub = asSub(bLow, aLow.tsym);
 1067                               highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym);
 1068                           }
 1069                           if (highSub != null) {
 1070                               if (!(a.tsym == highSub.tsym && a.tsym == lowSub.tsym)) {
 1071                                   Assert.error(a.tsym + " != " + highSub.tsym + " != " + lowSub.tsym);
 1072                               }
 1073                               if (!disjointTypes(aHigh.allparams(), highSub.allparams())
 1074                                   && !disjointTypes(aHigh.allparams(), lowSub.allparams())
 1075                                   && !disjointTypes(aLow.allparams(), highSub.allparams())
 1076                                   && !disjointTypes(aLow.allparams(), lowSub.allparams())) {
 1077                                   if (upcast ? giveWarning(a, b) :
 1078                                       giveWarning(b, a))
 1079                                       warnStack.head.warn(LintCategory.UNCHECKED);
 1080                                   return true;
 1081                               }
 1082                           }
 1083                           if (isReifiable(s))
 1084                               return isSubtypeUnchecked(a, b);
 1085                           else
 1086                               return isSubtypeUnchecked(a, b, warnStack.head);
 1087                       }
 1088   
 1089                       // Sidecast
 1090                       if (s.tag == CLASS) {
 1091                           if ((s.tsym.flags() & INTERFACE) != 0) {
 1092                               return ((t.tsym.flags() & FINAL) == 0)
 1093                                   ? sideCast(t, s, warnStack.head)
 1094                                   : sideCastFinal(t, s, warnStack.head);
 1095                           } else if ((t.tsym.flags() & INTERFACE) != 0) {
 1096                               return ((s.tsym.flags() & FINAL) == 0)
 1097                                   ? sideCast(t, s, warnStack.head)
 1098                                   : sideCastFinal(t, s, warnStack.head);
 1099                           } else {
 1100                               // unrelated class types
 1101                               return false;
 1102                           }
 1103                       }
 1104                   }
 1105                   return false;
 1106               }
 1107   
 1108               @Override
 1109               public Boolean visitArrayType(ArrayType t, Type s) {
 1110                   switch (s.tag) {
 1111                   case ERROR:
 1112                   case BOT:
 1113                       return true;
 1114                   case TYPEVAR:
 1115                       if (isCastable(s, t, Warner.noWarnings)) {
 1116                           warnStack.head.warn(LintCategory.UNCHECKED);
 1117                           return true;
 1118                       } else {
 1119                           return false;
 1120                       }
 1121                   case CLASS:
 1122                       return isSubtype(t, s);
 1123                   case ARRAY:
 1124                       if (elemtype(t).tag <= lastBaseTag ||
 1125                               elemtype(s).tag <= lastBaseTag) {
 1126                           return elemtype(t).tag == elemtype(s).tag;
 1127                       } else {
 1128                           return visit(elemtype(t), elemtype(s));
 1129                       }
 1130                   default:
 1131                       return false;
 1132                   }
 1133               }
 1134   
 1135               @Override
 1136               public Boolean visitTypeVar(TypeVar t, Type s) {
 1137                   switch (s.tag) {
 1138                   case ERROR:
 1139                   case BOT:
 1140                       return true;
 1141                   case TYPEVAR:
 1142                       if (isSubtype(t, s)) {
 1143                           return true;
 1144                       } else if (isCastable(t.bound, s, Warner.noWarnings)) {
 1145                           warnStack.head.warn(LintCategory.UNCHECKED);
 1146                           return true;
 1147                       } else {
 1148                           return false;
 1149                       }
 1150                   default:
 1151                       return isCastable(t.bound, s, warnStack.head);
 1152                   }
 1153               }
 1154   
 1155               @Override
 1156               public Boolean visitErrorType(ErrorType t, Type s) {
 1157                   return true;
 1158               }
 1159           };
 1160       // </editor-fold>
 1161   
 1162       // <editor-fold defaultstate="collapsed" desc="disjointTypes">
 1163       public boolean disjointTypes(List<Type> ts, List<Type> ss) {
 1164           while (ts.tail != null && ss.tail != null) {
 1165               if (disjointType(ts.head, ss.head)) return true;
 1166               ts = ts.tail;
 1167               ss = ss.tail;
 1168           }
 1169           return false;
 1170       }
 1171   
 1172       /**
 1173        * Two types or wildcards are considered disjoint if it can be
 1174        * proven that no type can be contained in both. It is
 1175        * conservative in that it is allowed to say that two types are
 1176        * not disjoint, even though they actually are.
 1177        *
 1178        * The type C<X> is castable to C<Y> exactly if X and Y are not
 1179        * disjoint.
 1180        */
 1181       public boolean disjointType(Type t, Type s) {
 1182           return disjointType.visit(t, s);
 1183       }
 1184       // where
 1185           private TypeRelation disjointType = new TypeRelation() {
 1186   
 1187               private Set<TypePair> cache = new HashSet<TypePair>();
 1188   
 1189               public Boolean visitType(Type t, Type s) {
 1190                   if (s.tag == WILDCARD)
 1191                       return visit(s, t);
 1192                   else
 1193                       return notSoftSubtypeRecursive(t, s) || notSoftSubtypeRecursive(s, t);
 1194               }
 1195   
 1196               private boolean isCastableRecursive(Type t, Type s) {
 1197                   TypePair pair = new TypePair(t, s);
 1198                   if (cache.add(pair)) {
 1199                       try {
 1200                           return Types.this.isCastable(t, s);
 1201                       } finally {
 1202                           cache.remove(pair);
 1203                       }
 1204                   } else {
 1205                       return true;
 1206                   }
 1207               }
 1208   
 1209               private boolean notSoftSubtypeRecursive(Type t, Type s) {
 1210                   TypePair pair = new TypePair(t, s);
 1211                   if (cache.add(pair)) {
 1212                       try {
 1213                           return Types.this.notSoftSubtype(t, s);
 1214                       } finally {
 1215                           cache.remove(pair);
 1216                       }
 1217                   } else {
 1218                       return false;
 1219                   }
 1220               }
 1221   
 1222               @Override
 1223               public Boolean visitWildcardType(WildcardType t, Type s) {
 1224                   if (t.isUnbound())
 1225                       return false;
 1226   
 1227                   if (s.tag != WILDCARD) {
 1228                       if (t.isExtendsBound())
 1229                           return notSoftSubtypeRecursive(s, t.type);
 1230                       else // isSuperBound()
 1231                           return notSoftSubtypeRecursive(t.type, s);
 1232                   }
 1233   
 1234                   if (s.isUnbound())
 1235                       return false;
 1236   
 1237                   if (t.isExtendsBound()) {
 1238                       if (s.isExtendsBound())
 1239                           return !isCastableRecursive(t.type, upperBound(s));
 1240                       else if (s.isSuperBound())
 1241                           return notSoftSubtypeRecursive(lowerBound(s), t.type);
 1242                   } else if (t.isSuperBound()) {
 1243                       if (s.isExtendsBound())
 1244                           return notSoftSubtypeRecursive(t.type, upperBound(s));
 1245                   }
 1246                   return false;
 1247               }
 1248           };
 1249       // </editor-fold>
 1250   
 1251       // <editor-fold defaultstate="collapsed" desc="lowerBoundArgtypes">
 1252       /**
 1253        * Returns the lower bounds of the formals of a method.
 1254        */
 1255       public List<Type> lowerBoundArgtypes(Type t) {
 1256           return map(t.getParameterTypes(), lowerBoundMapping);
 1257       }
 1258       private final Mapping lowerBoundMapping = new Mapping("lowerBound") {
 1259               public Type apply(Type t) {
 1260                   return lowerBound(t);
 1261               }
 1262           };
 1263       // </editor-fold>
 1264   
 1265       // <editor-fold defaultstate="collapsed" desc="notSoftSubtype">
 1266       /**
 1267        * This relation answers the question: is impossible that
 1268        * something of type `t' can be a subtype of `s'? This is
 1269        * different from the question "is `t' not a subtype of `s'?"
 1270        * when type variables are involved: Integer is not a subtype of T
 1271        * where <T extends Number> but it is not true that Integer cannot
 1272        * possibly be a subtype of T.
 1273        */
 1274       public boolean notSoftSubtype(Type t, Type s) {
 1275           if (t == s) return false;
 1276           if (t.tag == TYPEVAR) {
 1277               TypeVar tv = (TypeVar) t;
 1278               return !isCastable(tv.bound,
 1279                                  relaxBound(s),
 1280                                  Warner.noWarnings);
 1281           }
 1282           if (s.tag != WILDCARD)
 1283               s = upperBound(s);
 1284   
 1285           return !isSubtype(t, relaxBound(s));
 1286       }
 1287   
 1288       private Type relaxBound(Type t) {
 1289           if (t.tag == TYPEVAR) {
 1290               while (t.tag == TYPEVAR)
 1291                   t = t.getUpperBound();
 1292               t = rewriteQuantifiers(t, true, true);
 1293           }
 1294           return t;
 1295       }
 1296       // </editor-fold>
 1297   
 1298       // <editor-fold defaultstate="collapsed" desc="isReifiable">
 1299       public boolean isReifiable(Type t) {
 1300           return isReifiable.visit(t);
 1301       }
 1302       // where
 1303           private UnaryVisitor<Boolean> isReifiable = new UnaryVisitor<Boolean>() {
 1304   
 1305               public Boolean visitType(Type t, Void ignored) {
 1306                   return true;
 1307               }
 1308   
 1309               @Override
 1310               public Boolean visitClassType(ClassType t, Void ignored) {
 1311                   if (t.isCompound())
 1312                       return false;
 1313                   else {
 1314                       if (!t.isParameterized())
 1315                           return true;
 1316   
 1317                       for (Type param : t.allparams()) {
 1318                           if (!param.isUnbound())
 1319                               return false;
 1320                       }
 1321                       return true;
 1322                   }
 1323               }
 1324   
 1325               @Override
 1326               public Boolean visitArrayType(ArrayType t, Void ignored) {
 1327                   return visit(t.elemtype);
 1328               }
 1329   
 1330               @Override
 1331               public Boolean visitTypeVar(TypeVar t, Void ignored) {
 1332                   return false;
 1333               }
 1334           };
 1335       // </editor-fold>
 1336   
 1337       // <editor-fold defaultstate="collapsed" desc="Array Utils">
 1338       public boolean isArray(Type t) {
 1339           while (t.tag == WILDCARD)
 1340               t = upperBound(t);
 1341           return t.tag == ARRAY;
 1342       }
 1343   
 1344       /**
 1345        * The element type of an array.
 1346        */
 1347       public Type elemtype(Type t) {
 1348           switch (t.tag) {
 1349           case WILDCARD:
 1350               return elemtype(upperBound(t));
 1351           case ARRAY:
 1352               return ((ArrayType)t).elemtype;
 1353           case FORALL:
 1354               return elemtype(((ForAll)t).qtype);
 1355           case ERROR:
 1356               return t;
 1357           default:
 1358               return null;
 1359           }
 1360       }
 1361   
 1362       public Type elemtypeOrType(Type t) {
 1363           Type elemtype = elemtype(t);
 1364           return elemtype != null ?
 1365               elemtype :
 1366               t;
 1367       }
 1368   
 1369       /**
 1370        * Mapping to take element type of an arraytype
 1371        */
 1372       private Mapping elemTypeFun = new Mapping ("elemTypeFun") {
 1373           public Type apply(Type t) { return elemtype(t); }
 1374       };
 1375   
 1376       /**
 1377        * The number of dimensions of an array type.
 1378        */
 1379       public int dimensions(Type t) {
 1380           int result = 0;
 1381           while (t.tag == ARRAY) {
 1382               result++;
 1383               t = elemtype(t);
 1384           }
 1385           return result;
 1386       }
 1387       // </editor-fold>
 1388   
 1389       // <editor-fold defaultstate="collapsed" desc="asSuper">
 1390       /**
 1391        * Return the (most specific) base type of t that starts with the
 1392        * given symbol.  If none exists, return null.
 1393        *
 1394        * @param t a type
 1395        * @param sym a symbol
 1396        */
 1397       public Type asSuper(Type t, Symbol sym) {
 1398           return asSuper.visit(t, sym);
 1399       }
 1400       // where
 1401           private SimpleVisitor<Type,Symbol> asSuper = new SimpleVisitor<Type,Symbol>() {
 1402   
 1403               public Type visitType(Type t, Symbol sym) {
 1404                   return null;
 1405               }
 1406   
 1407               @Override
 1408               public Type visitClassType(ClassType t, Symbol sym) {
 1409                   if (t.tsym == sym)
 1410                       return t;
 1411   
 1412                   Type st = supertype(t);
 1413                   if (st.tag == CLASS || st.tag == TYPEVAR || st.tag == ERROR) {
 1414                       Type x = asSuper(st, sym);
 1415                       if (x != null)
 1416                           return x;
 1417                   }
 1418                   if ((sym.flags() & INTERFACE) != 0) {
 1419                       for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
 1420                           Type x = asSuper(l.head, sym);
 1421                           if (x != null)
 1422                               return x;
 1423                       }
 1424                   }
 1425                   return null;
 1426               }
 1427   
 1428               @Override
 1429               public Type visitArrayType(ArrayType t, Symbol sym) {
 1430                   return isSubtype(t, sym.type) ? sym.type : null;
 1431               }
 1432   
 1433               @Override
 1434               public Type visitTypeVar(TypeVar t, Symbol sym) {
 1435                   if (t.tsym == sym)
 1436                       return t;
 1437                   else
 1438                       return asSuper(t.bound, sym);
 1439               }
 1440   
 1441               @Override
 1442               public Type visitErrorType(ErrorType t, Symbol sym) {
 1443                   return t;
 1444               }
 1445           };
 1446   
 1447       /**
 1448        * Return the base type of t or any of its outer types that starts
 1449        * with the given symbol.  If none exists, return null.
 1450        *
 1451        * @param t a type
 1452        * @param sym a symbol
 1453        */
 1454       public Type asOuterSuper(Type t, Symbol sym) {
 1455           switch (t.tag) {
 1456           case CLASS:
 1457               do {
 1458                   Type s = asSuper(t, sym);
 1459                   if (s != null) return s;
 1460                   t = t.getEnclosingType();
 1461               } while (t.tag == CLASS);
 1462               return null;
 1463           case ARRAY:
 1464               return isSubtype(t, sym.type) ? sym.type : null;
 1465           case TYPEVAR:
 1466               return asSuper(t, sym);
 1467           case ERROR:
 1468               return t;
 1469           default:
 1470               return null;
 1471           }
 1472       }
 1473   
 1474       /**
 1475        * Return the base type of t or any of its enclosing types that
 1476        * starts with the given symbol.  If none exists, return null.
 1477        *
 1478        * @param t a type
 1479        * @param sym a symbol
 1480        */
 1481       public Type asEnclosingSuper(Type t, Symbol sym) {
 1482           switch (t.tag) {
 1483           case CLASS:
 1484               do {
 1485                   Type s = asSuper(t, sym);
 1486                   if (s != null) return s;
 1487                   Type outer = t.getEnclosingType();
 1488                   t = (outer.tag == CLASS) ? outer :
 1489                       (t.tsym.owner.enclClass() != null) ? t.tsym.owner.enclClass().type :
 1490                       Type.noType;
 1491               } while (t.tag == CLASS);
 1492               return null;
 1493           case ARRAY:
 1494               return isSubtype(t, sym.type) ? sym.type : null;
 1495           case TYPEVAR:
 1496               return asSuper(t, sym);
 1497           case ERROR:
 1498               return t;
 1499           default:
 1500               return null;
 1501           }
 1502       }
 1503       // </editor-fold>
 1504   
 1505       // <editor-fold defaultstate="collapsed" desc="memberType">
 1506       /**
 1507        * The type of given symbol, seen as a member of t.
 1508        *
 1509        * @param t a type
 1510        * @param sym a symbol
 1511        */
 1512       public Type memberType(Type t, Symbol sym) {
 1513           return (sym.flags() & STATIC) != 0
 1514               ? sym.type
 1515               : memberType.visit(t, sym);
 1516           }
 1517       // where
 1518           private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
 1519   
 1520               public Type visitType(Type t, Symbol sym) {
 1521                   return sym.type;
 1522               }
 1523   
 1524               @Override
 1525               public Type visitWildcardType(WildcardType t, Symbol sym) {
 1526                   return memberType(upperBound(t), sym);
 1527               }
 1528   
 1529               @Override
 1530               public Type visitClassType(ClassType t, Symbol sym) {
 1531                   Symbol owner = sym.owner;
 1532                   long flags = sym.flags();
 1533                   if (((flags & STATIC) == 0) && owner.type.isParameterized()) {
 1534                       Type base = asOuterSuper(t, owner);
 1535                       //if t is an intersection type T = CT & I1 & I2 ... & In
 1536                       //its supertypes CT, I1, ... In might contain wildcards
 1537                       //so we need to go through capture conversion
 1538                       base = t.isCompound() ? capture(base) : base;
 1539                       if (base != null) {
 1540                           List<Type> ownerParams = owner.type.allparams();
 1541                           List<Type> baseParams = base.allparams();
 1542                           if (ownerParams.nonEmpty()) {
 1543                               if (baseParams.isEmpty()) {
 1544                                   // then base is a raw type
 1545                                   return erasure(sym.type);
 1546                               } else {
 1547                                   return subst(sym.type, ownerParams, baseParams);
 1548                               }
 1549                           }
 1550                       }
 1551                   }
 1552                   return sym.type;
 1553               }
 1554   
 1555               @Override
 1556               public Type visitTypeVar(TypeVar t, Symbol sym) {
 1557                   return memberType(t.bound, sym);
 1558               }
 1559   
 1560               @Override
 1561               public Type visitErrorType(ErrorType t, Symbol sym) {
 1562                   return t;
 1563               }
 1564           };
 1565       // </editor-fold>
 1566   
 1567       // <editor-fold defaultstate="collapsed" desc="isAssignable">
 1568       public boolean isAssignable(Type t, Type s) {
 1569           return isAssignable(t, s, Warner.noWarnings);
 1570       }
 1571   
 1572       /**
 1573        * Is t assignable to s?<br>
 1574        * Equivalent to subtype except for constant values and raw
 1575        * types.<br>
 1576        * (not defined for Method and ForAll types)
 1577        */
 1578       public boolean isAssignable(Type t, Type s, Warner warn) {
 1579           if (t.tag == ERROR)
 1580               return true;
 1581           if (t.tag <= INT && t.constValue() != null) {
 1582               int value = ((Number)t.constValue()).intValue();
 1583               switch (s.tag) {
 1584               case BYTE:
 1585                   if (Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE)
 1586                       return true;
 1587                   break;
 1588               case CHAR:
 1589                   if (Character.MIN_VALUE <= value && value <= Character.MAX_VALUE)
 1590                       return true;
 1591                   break;
 1592               case SHORT:
 1593                   if (Short.MIN_VALUE <= value && value <= Short.MAX_VALUE)
 1594                       return true;
 1595                   break;
 1596               case INT:
 1597                   return true;
 1598               case CLASS:
 1599                   switch (unboxedType(s).tag) {
 1600                   case BYTE:
 1601                   case CHAR:
 1602                   case SHORT:
 1603                       return isAssignable(t, unboxedType(s), warn);
 1604                   }
 1605                   break;
 1606               }
 1607           }
 1608           return isConvertible(t, s, warn);
 1609       }
 1610       // </editor-fold>
 1611   
 1612       // <editor-fold defaultstate="collapsed" desc="erasure">
 1613       /**
 1614        * The erasure of t {@code |t|} -- the type that results when all
 1615        * type parameters in t are deleted.
 1616        */
 1617       public Type erasure(Type t) {
 1618           return erasure(t, false);
 1619       }
 1620       //where
 1621       private Type erasure(Type t, boolean recurse) {
 1622           if (t.tag <= lastBaseTag)
 1623               return t; /* fast special case */
 1624           else
 1625               return erasure.visit(t, recurse);
 1626           }
 1627       // where
 1628           private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() {
 1629               public Type visitType(Type t, Boolean recurse) {
 1630                   if (t.tag <= lastBaseTag)
 1631                       return t; /*fast special case*/
 1632                   else
 1633                       return t.map(recurse ? erasureRecFun : erasureFun);
 1634               }
 1635   
 1636               @Override
 1637               public Type visitWildcardType(WildcardType t, Boolean recurse) {
 1638                   return erasure(upperBound(t), recurse);
 1639               }
 1640   
 1641               @Override
 1642               public Type visitClassType(ClassType t, Boolean recurse) {
 1643                   Type erased = t.tsym.erasure(Types.this);
 1644                   if (recurse) {
 1645                       erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym);
 1646                   }
 1647                   return erased;
 1648               }
 1649   
 1650               @Override
 1651               public Type visitTypeVar(TypeVar t, Boolean recurse) {
 1652                   return erasure(t.bound, recurse);
 1653               }
 1654   
 1655               @Override
 1656               public Type visitErrorType(ErrorType t, Boolean recurse) {
 1657                   return t;
 1658               }
 1659           };
 1660   
 1661       private Mapping erasureFun = new Mapping ("erasure") {
 1662               public Type apply(Type t) { return erasure(t); }
 1663           };
 1664   
 1665       private Mapping erasureRecFun = new Mapping ("erasureRecursive") {
 1666           public Type apply(Type t) { return erasureRecursive(t); }
 1667       };
 1668   
 1669       public List<Type> erasure(List<Type> ts) {
 1670           return Type.map(ts, erasureFun);
 1671       }
 1672   
 1673       public Type erasureRecursive(Type t) {
 1674           return erasure(t, true);
 1675       }
 1676   
 1677       public List<Type> erasureRecursive(List<Type> ts) {
 1678           return Type.map(ts, erasureRecFun);
 1679       }
 1680       // </editor-fold>
 1681   
 1682       // <editor-fold defaultstate="collapsed" desc="makeCompoundType">
 1683       /**
 1684        * Make a compound type from non-empty list of types
 1685        *
 1686        * @param bounds            the types from which the compound type is formed
 1687        * @param supertype         is objectType if all bounds are interfaces,
 1688        *                          null otherwise.
 1689        */
 1690       public Type makeCompoundType(List<Type> bounds,
 1691                                    Type supertype) {
 1692           ClassSymbol bc =
 1693               new ClassSymbol(ABSTRACT|PUBLIC|SYNTHETIC|COMPOUND|ACYCLIC,
 1694                               Type.moreInfo
 1695                                   ? names.fromString(bounds.toString())
 1696                                   : names.empty,
 1697                               syms.noSymbol);
 1698           if (bounds.head.tag == TYPEVAR)
 1699               // error condition, recover
 1700                   bc.erasure_field = syms.objectType;
 1701               else
 1702                   bc.erasure_field = erasure(bounds.head);
 1703               bc.members_field = new Scope(bc);
 1704           ClassType bt = (ClassType)bc.type;
 1705           bt.allparams_field = List.nil();
 1706           if (supertype != null) {
 1707               bt.supertype_field = supertype;
 1708               bt.interfaces_field = bounds;
 1709           } else {
 1710               bt.supertype_field = bounds.head;
 1711               bt.interfaces_field = bounds.tail;
 1712           }
 1713           Assert.check(bt.supertype_field.tsym.completer != null
 1714                   || !bt.supertype_field.isInterface(),
 1715               bt.supertype_field);
 1716           return bt;
 1717       }
 1718   
 1719       /**
 1720        * Same as {@link #makeCompoundType(List,Type)}, except that the
 1721        * second parameter is computed directly. Note that this might
 1722        * cause a symbol completion.  Hence, this version of
 1723        * makeCompoundType may not be called during a classfile read.
 1724        */
 1725       public Type makeCompoundType(List<Type> bounds) {
 1726           Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ?
 1727               supertype(bounds.head) : null;
 1728           return makeCompoundType(bounds, supertype);
 1729       }
 1730   
 1731       /**
 1732        * A convenience wrapper for {@link #makeCompoundType(List)}; the
 1733        * arguments are converted to a list and passed to the other
 1734        * method.  Note that this might cause a symbol completion.
 1735        * Hence, this version of makeCompoundType may not be called
 1736        * during a classfile read.
 1737        */
 1738       public Type makeCompoundType(Type bound1, Type bound2) {
 1739           return makeCompoundType(List.of(bound1, bound2));
 1740       }
 1741       // </editor-fold>
 1742   
 1743       // <editor-fold defaultstate="collapsed" desc="supertype">
 1744       public Type supertype(Type t) {
 1745           return supertype.visit(t);
 1746       }
 1747       // where
 1748           private UnaryVisitor<Type> supertype = new UnaryVisitor<Type>() {
 1749   
 1750               public Type visitType(Type t, Void ignored) {
 1751                   // A note on wildcards: there is no good way to
 1752                   // determine a supertype for a super bounded wildcard.
 1753                   return null;
 1754               }
 1755   
 1756               @Override
 1757               public Type visitClassType(ClassType t, Void ignored) {
 1758                   if (t.supertype_field == null) {
 1759                       Type supertype = ((ClassSymbol)t.tsym).getSuperclass();
 1760                       // An interface has no superclass; its supertype is Object.
 1761                       if (t.isInterface())
 1762                           supertype = ((ClassType)t.tsym.type).supertype_field;
 1763                       if (t.supertype_field == null) {
 1764                           List<Type> actuals = classBound(t).allparams();
 1765                           List<Type> formals = t.tsym.type.allparams();
 1766                           if (t.hasErasedSupertypes()) {
 1767                               t.supertype_field = erasureRecursive(supertype);
 1768                           } else if (formals.nonEmpty()) {
 1769                               t.supertype_field = subst(supertype, formals, actuals);
 1770                           }
 1771                           else {
 1772                               t.supertype_field = supertype;
 1773                           }
 1774                       }
 1775                   }
 1776                   return t.supertype_field;
 1777               }
 1778   
 1779               /**
 1780                * The supertype is always a class type. If the type
 1781                * variable's bounds start with a class type, this is also
 1782                * the supertype.  Otherwise, the supertype is
 1783                * java.lang.Object.
 1784                */
 1785               @Override
 1786               public Type visitTypeVar(TypeVar t, Void ignored) {
 1787                   if (t.bound.tag == TYPEVAR ||
 1788                       (!t.bound.isCompound() && !t.bound.isInterface())) {
 1789                       return t.bound;
 1790                   } else {
 1791                       return supertype(t.bound);
 1792                   }
 1793               }
 1794   
 1795               @Override
 1796               public Type visitArrayType(ArrayType t, Void ignored) {
 1797                   if (t.elemtype.isPrimitive() || isSameType(t.elemtype, syms.objectType))
 1798                       return arraySuperType();
 1799                   else
 1800                       return new ArrayType(supertype(t.elemtype), t.tsym);
 1801               }
 1802   
 1803               @Override
 1804               public Type visitErrorType(ErrorType t, Void ignored) {
 1805                   return t;
 1806               }
 1807           };
 1808       // </editor-fold>
 1809   
 1810       // <editor-fold defaultstate="collapsed" desc="interfaces">
 1811       /**
 1812        * Return the interfaces implemented by this class.
 1813        */
 1814       public List<Type> interfaces(Type t) {
 1815           return interfaces.visit(t);
 1816       }
 1817       // where
 1818           private UnaryVisitor<List<Type>> interfaces = new UnaryVisitor<List<Type>>() {
 1819   
 1820               public List<Type> visitType(Type t, Void ignored) {
 1821                   return List.nil();
 1822               }
 1823   
 1824               @Override
 1825               public List<Type> visitClassType(ClassType t, Void ignored) {
 1826                   if (t.interfaces_field == null) {
 1827                       List<Type> interfaces = ((ClassSymbol)t.tsym).getInterfaces();
 1828                       if (t.interfaces_field == null) {
 1829                           // If t.interfaces_field is null, then t must
 1830                           // be a parameterized type (not to be confused
 1831                           // with a generic type declaration).
 1832                           // Terminology:
 1833                           //    Parameterized type: List<String>
 1834                           //    Generic type declaration: class List<E> { ... }
 1835                           // So t corresponds to List<String> and
 1836                           // t.tsym.type corresponds to List<E>.
 1837                           // The reason t must be parameterized type is
 1838                           // that completion will happen as a side
 1839                           // effect of calling
 1840                           // ClassSymbol.getInterfaces.  Since
 1841                           // t.interfaces_field is null after
 1842                           // completion, we can assume that t is not the
 1843                           // type of a class/interface declaration.
 1844                           Assert.check(t != t.tsym.type, t);
 1845                           List<Type> actuals = t.allparams();
 1846                           List<Type> formals = t.tsym.type.allparams();
 1847                           if (t.hasErasedSupertypes()) {
 1848                               t.interfaces_field = erasureRecursive(interfaces);
 1849                           } else if (formals.nonEmpty()) {
 1850                               t.interfaces_field =
 1851                                   upperBounds(subst(interfaces, formals, actuals));
 1852                           }
 1853                           else {
 1854                               t.interfaces_field = interfaces;
 1855                           }
 1856                       }
 1857                   }
 1858                   return t.interfaces_field;
 1859               }
 1860   
 1861               @Override
 1862               public List<Type> visitTypeVar(TypeVar t, Void ignored) {
 1863                   if (t.bound.isCompound())
 1864                       return interfaces(t.bound);
 1865   
 1866                   if (t.bound.isInterface())
 1867                       return List.of(t.bound);
 1868   
 1869                   return List.nil();
 1870               }
 1871           };
 1872       // </editor-fold>
 1873   
 1874       // <editor-fold defaultstate="collapsed" desc="isDerivedRaw">
 1875       Map<Type,Boolean> isDerivedRawCache = new HashMap<Type,Boolean>();
 1876   
 1877       public boolean isDerivedRaw(Type t) {
 1878           Boolean result = isDerivedRawCache.get(t);
 1879           if (result == null) {
 1880               result = isDerivedRawInternal(t);
 1881               isDerivedRawCache.put(t, result);
 1882           }
 1883           return result;
 1884       }
 1885   
 1886       public boolean isDerivedRawInternal(Type t) {
 1887           if (t.isErroneous())
 1888               return false;
 1889           return
 1890               t.isRaw() ||
 1891               supertype(t) != null && isDerivedRaw(supertype(t)) ||
 1892               isDerivedRaw(interfaces(t));
 1893       }
 1894   
 1895       public boolean isDerivedRaw(List<Type> ts) {
 1896           List<Type> l = ts;
 1897           while (l.nonEmpty() && !isDerivedRaw(l.head)) l = l.tail;
 1898           return l.nonEmpty();
 1899       }
 1900       // </editor-fold>
 1901   
 1902       // <editor-fold defaultstate="collapsed" desc="setBounds">
 1903       /**
 1904        * Set the bounds field of the given type variable to reflect a
 1905        * (possibly multiple) list of bounds.
 1906        * @param t                 a type variable
 1907        * @param bounds            the bounds, must be nonempty
 1908        * @param supertype         is objectType if all bounds are interfaces,
 1909        *                          null otherwise.
 1910        */
 1911       public void setBounds(TypeVar t, List<Type> bounds, Type supertype) {
 1912           if (bounds.tail.isEmpty())
 1913               t.bound = bounds.head;
 1914           else
 1915               t.bound = makeCompoundType(bounds, supertype);
 1916           t.rank_field = -1;
 1917       }
 1918   
 1919       /**
 1920        * Same as {@link #setBounds(Type.TypeVar,List,Type)}, except that
 1921        * third parameter is computed directly, as follows: if all
 1922        * all bounds are interface types, the computed supertype is Object,
 1923        * otherwise the supertype is simply left null (in this case, the supertype
 1924        * is assumed to be the head of the bound list passed as second argument).
 1925        * Note that this check might cause a symbol completion. Hence, this version of
 1926        * setBounds may not be called during a classfile read.
 1927        */
 1928       public void setBounds(TypeVar t, List<Type> bounds) {
 1929           Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ?
 1930               syms.objectType : null;
 1931           setBounds(t, bounds, supertype);
 1932           t.rank_field = -1;
 1933       }
 1934       // </editor-fold>
 1935   
 1936       // <editor-fold defaultstate="collapsed" desc="getBounds">
 1937       /**
 1938        * Return list of bounds of the given type variable.
 1939        */
 1940       public List<Type> getBounds(TypeVar t) {
 1941           if (t.bound.isErroneous() || !t.bound.isCompound())
 1942               return List.of(t.bound);
 1943           else if ((erasure(t).tsym.flags() & INTERFACE) == 0)
 1944               return interfaces(t).prepend(supertype(t));
 1945           else
 1946               // No superclass was given in bounds.
 1947               // In this case, supertype is Object, erasure is first interface.
 1948               return interfaces(t);
 1949       }
 1950       // </editor-fold>
 1951   
 1952       // <editor-fold defaultstate="collapsed" desc="classBound">
 1953       /**
 1954        * If the given type is a (possibly selected) type variable,
 1955        * return the bounding class of this type, otherwise return the
 1956        * type itself.
 1957        */
 1958       public Type classBound(Type t) {
 1959           return classBound.visit(t);
 1960       }
 1961       // where
 1962           private UnaryVisitor<Type> classBound = new UnaryVisitor<Type>() {
 1963   
 1964               public Type visitType(Type t, Void ignored) {
 1965                   return t;
 1966               }
 1967   
 1968               @Override
 1969               public Type visitClassType(ClassType t, Void ignored) {
 1970                   Type outer1 = classBound(t.getEnclosingType());
 1971                   if (outer1 != t.getEnclosingType())
 1972                       return new ClassType(outer1, t.getTypeArguments(), t.tsym);
 1973                   else
 1974                       return t;
 1975               }
 1976   
 1977               @Override
 1978               public Type visitTypeVar(TypeVar t, Void ignored) {
 1979                   return classBound(supertype(t));
 1980               }
 1981   
 1982               @Override
 1983               public Type visitErrorType(ErrorType t, Void ignored) {
 1984                   return t;
 1985               }
 1986           };
 1987       // </editor-fold>
 1988   
 1989       // <editor-fold defaultstate="collapsed" desc="sub signature / override equivalence">
 1990       /**
 1991        * Returns true iff the first signature is a <em>sub
 1992        * signature</em> of the other.  This is <b>not</b> an equivalence
 1993        * relation.
 1994        *
 1995        * @jls section 8.4.2.
 1996        * @see #overrideEquivalent(Type t, Type s)
 1997        * @param t first signature (possibly raw).
 1998        * @param s second signature (could be subjected to erasure).
 1999        * @return true if t is a sub signature of s.
 2000        */
 2001       public boolean isSubSignature(Type t, Type s) {
 2002           return isSubSignature(t, s, true);
 2003       }
 2004   
 2005       public boolean isSubSignature(Type t, Type s, boolean strict) {
 2006           return hasSameArgs(t, s, strict) || hasSameArgs(t, erasure(s), strict);
 2007       }
 2008   
 2009       /**
 2010        * Returns true iff these signatures are related by <em>override
 2011        * equivalence</em>.  This is the natural extension of
 2012        * isSubSignature to an equivalence relation.
 2013        *
 2014        * @jls section 8.4.2.
 2015        * @see #isSubSignature(Type t, Type s)
 2016        * @param t a signature (possible raw, could be subjected to
 2017        * erasure).
 2018        * @param s a signature (possible raw, could be subjected to
 2019        * erasure).
 2020        * @return true if either argument is a sub signature of the other.
 2021        */
 2022       public boolean overrideEquivalent(Type t, Type s) {
 2023           return hasSameArgs(t, s) ||
 2024               hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s);
 2025       }
 2026   
 2027       // <editor-fold defaultstate="collapsed" desc="Determining method implementation in given site">
 2028       class ImplementationCache {
 2029   
 2030           private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, Entry>>> _map =
 2031                   new WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, Entry>>>();
 2032   
 2033           class Entry {
 2034               final MethodSymbol cachedImpl;
 2035               final Filter<Symbol> implFilter;
 2036               final boolean checkResult;
 2037               final int prevMark;
 2038   
 2039               public Entry(MethodSymbol cachedImpl,
 2040                       Filter<Symbol> scopeFilter,
 2041                       boolean checkResult,
 2042                       int prevMark) {
 2043                   this.cachedImpl = cachedImpl;
 2044                   this.implFilter = scopeFilter;
 2045                   this.checkResult = checkResult;
 2046                   this.prevMark = prevMark;
 2047               }
 2048   
 2049               boolean matches(Filter<Symbol> scopeFilter, boolean checkResult, int mark) {
 2050                   return this.implFilter == scopeFilter &&
 2051                           this.checkResult == checkResult &&
 2052                           this.prevMark == mark;
 2053               }
 2054           }
 2055   
 2056           MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
 2057               SoftReference<Map<TypeSymbol, Entry>> ref_cache = _map.get(ms);
 2058               Map<TypeSymbol, Entry> cache = ref_cache != null ? ref_cache.get() : null;
 2059               if (cache == null) {
 2060                   cache = new HashMap<TypeSymbol, Entry>();
 2061                   _map.put(ms, new SoftReference<Map<TypeSymbol, Entry>>(cache));
 2062               }
 2063               Entry e = cache.get(origin);
 2064               CompoundScope members = membersClosure(origin.type, true);
 2065               if (e == null ||
 2066                       !e.matches(implFilter, checkResult, members.getMark())) {
 2067                   MethodSymbol impl = implementationInternal(ms, origin, checkResult, implFilter);
 2068                   cache.put(origin, new Entry(impl, implFilter, checkResult, members.getMark()));
 2069                   return impl;
 2070               }
 2071               else {
 2072                   return e.cachedImpl;
 2073               }
 2074           }
 2075   
 2076           private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
 2077               for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = supertype(t)) {
 2078                   while (t.tag == TYPEVAR)
 2079                       t = t.getUpperBound();
 2080                   TypeSymbol c = t.tsym;
 2081                   for (Scope.Entry e = c.members().lookup(ms.name, implFilter);
 2082                        e.scope != null;
 2083                        e = e.next(implFilter)) {
 2084                       if (e.sym != null &&
 2085                                e.sym.overrides(ms, origin, Types.this, checkResult))
 2086                           return (MethodSymbol)e.sym;
 2087                   }
 2088               }
 2089               return null;
 2090           }
 2091       }
 2092   
 2093       private ImplementationCache implCache = new ImplementationCache();
 2094   
 2095       public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
 2096           return implCache.get(ms, origin, checkResult, implFilter);
 2097       }
 2098       // </editor-fold>
 2099   
 2100       // <editor-fold defaultstate="collapsed" desc="compute transitive closure of all members in given site">
 2101       class MembersClosureCache extends SimpleVisitor<CompoundScope, Boolean> {
 2102   
 2103           private WeakHashMap<TypeSymbol, Entry> _map =
 2104                   new WeakHashMap<TypeSymbol, Entry>();
 2105   
 2106           class Entry {
 2107               final boolean skipInterfaces;
 2108               final CompoundScope compoundScope;
 2109   
 2110               public Entry(boolean skipInterfaces, CompoundScope compoundScope) {
 2111                   this.skipInterfaces = skipInterfaces;
 2112                   this.compoundScope = compoundScope;
 2113               }
 2114   
 2115               boolean matches(boolean skipInterfaces) {
 2116                   return this.skipInterfaces == skipInterfaces;
 2117               }
 2118           }
 2119   
 2120           /** members closure visitor methods **/
 2121   
 2122           public CompoundScope visitType(Type t, Boolean skipInterface) {
 2123               return null;
 2124           }
 2125   
 2126           @Override
 2127           public CompoundScope visitClassType(ClassType t, Boolean skipInterface) {
 2128               ClassSymbol csym = (ClassSymbol)t.tsym;
 2129               Entry e = _map.get(csym);
 2130               if (e == null || !e.matches(skipInterface)) {
 2131                   CompoundScope membersClosure = new CompoundScope(csym);
 2132                   if (!skipInterface) {
 2133                       for (Type i : interfaces(t)) {
 2134                           membersClosure.addSubScope(visit(i, skipInterface));
 2135                       }
 2136                   }
 2137                   membersClosure.addSubScope(visit(supertype(t), skipInterface));
 2138                   membersClosure.addSubScope(csym.members());
 2139                   e = new Entry(skipInterface, membersClosure);
 2140                   _map.put(csym, e);
 2141               }
 2142               return e.compoundScope;
 2143           }
 2144   
 2145           @Override
 2146           public CompoundScope visitTypeVar(TypeVar t, Boolean skipInterface) {
 2147               return visit(t.getUpperBound(), skipInterface);
 2148           }
 2149       }
 2150   
 2151       private MembersClosureCache membersCache = new MembersClosureCache();
 2152   
 2153       public CompoundScope membersClosure(Type site, boolean skipInterface) {
 2154           return membersCache.visit(site, skipInterface);
 2155       }
 2156       // </editor-fold>
 2157   
 2158       /**
 2159        * Does t have the same arguments as s?  It is assumed that both
 2160        * types are (possibly polymorphic) method types.  Monomorphic
 2161        * method types "have the same arguments", if their argument lists
 2162        * are equal.  Polymorphic method types "have the same arguments",
 2163        * if they have the same arguments after renaming all type
 2164        * variables of one to corresponding type variables in the other,
 2165        * where correspondence is by position in the type parameter list.
 2166        */
 2167       public boolean hasSameArgs(Type t, Type s) {
 2168           return hasSameArgs(t, s, true);
 2169       }
 2170   
 2171       public boolean hasSameArgs(Type t, Type s, boolean strict) {
 2172           return hasSameArgs(t, s, strict ? hasSameArgs_strict : hasSameArgs_nonstrict);
 2173       }
 2174   
 2175       private boolean hasSameArgs(Type t, Type s, TypeRelation hasSameArgs) {
 2176           return hasSameArgs.visit(t, s);
 2177       }
 2178       // where
 2179           private class HasSameArgs extends TypeRelation {
 2180   
 2181               boolean strict;
 2182   
 2183               public HasSameArgs(boolean strict) {
 2184                   this.strict = strict;
 2185               }
 2186   
 2187               public Boolean visitType(Type t, Type s) {
 2188                   throw new AssertionError();
 2189               }
 2190   
 2191               @Override
 2192               public Boolean visitMethodType(MethodType t, Type s) {
 2193                   return s.tag == METHOD
 2194                       && containsTypeEquivalent(t.argtypes, s.getParameterTypes());
 2195               }
 2196   
 2197               @Override
 2198               public Boolean visitForAll(ForAll t, Type s) {
 2199                   if (s.tag != FORALL)
 2200                       return strict ? false : visitMethodType(t.asMethodType(), s);
 2201   
 2202                   ForAll forAll = (ForAll)s;
 2203                   return hasSameBounds(t, forAll)
 2204                       && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
 2205               }
 2206   
 2207               @Override
 2208               public Boolean visitErrorType(ErrorType t, Type s) {
 2209                   return false;
 2210               }
 2211           };
 2212   
 2213           TypeRelation hasSameArgs_strict = new HasSameArgs(true);
 2214           TypeRelation hasSameArgs_nonstrict = new HasSameArgs(false);
 2215   
 2216       // </editor-fold>
 2217   
 2218       // <editor-fold defaultstate="collapsed" desc="subst">
 2219       public List<Type> subst(List<Type> ts,
 2220                               List<Type> from,
 2221                               List<Type> to) {
 2222           return new Subst(from, to).subst(ts);
 2223       }
 2224   
 2225       /**
 2226        * Substitute all occurrences of a type in `from' with the
 2227        * corresponding type in `to' in 't'. Match lists `from' and `to'
 2228        * from the right: If lists have different length, discard leading
 2229        * elements of the longer list.
 2230        */
 2231       public Type subst(Type t, List<Type> from, List<Type> to) {
 2232           return new Subst(from, to).subst(t);
 2233       }
 2234   
 2235       private class Subst extends UnaryVisitor<Type> {
 2236           List<Type> from;
 2237           List<Type> to;
 2238   
 2239           public Subst(List<Type> from, List<Type> to) {
 2240               int fromLength = from.length();
 2241               int toLength = to.length();
 2242               while (fromLength > toLength) {
 2243                   fromLength--;
 2244                   from = from.tail;
 2245               }
 2246               while (fromLength < toLength) {
 2247                   toLength--;
 2248                   to = to.tail;
 2249               }
 2250               this.from = from;
 2251               this.to = to;
 2252           }
 2253   
 2254           Type subst(Type t) {
 2255               if (from.tail == null)
 2256                   return t;
 2257               else
 2258                   return visit(t);
 2259               }
 2260   
 2261           List<Type> subst(List<Type> ts) {
 2262               if (from.tail == null)
 2263                   return ts;
 2264               boolean wild = false;
 2265               if (ts.nonEmpty() && from.nonEmpty()) {
 2266                   Type head1 = subst(ts.head);
 2267                   List<Type> tail1 = subst(ts.tail);
 2268                   if (head1 != ts.head || tail1 != ts.tail)
 2269                       return tail1.prepend(head1);
 2270               }
 2271               return ts;
 2272           }
 2273   
 2274           public Type visitType(Type t, Void ignored) {
 2275               return t;
 2276           }
 2277   
 2278           @Override
 2279           public Type visitMethodType(MethodType t, Void ignored) {
 2280               List<Type> argtypes = subst(t.argtypes);
 2281               Type restype = subst(t.restype);
 2282               List<Type> thrown = subst(t.thrown);
 2283               if (argtypes == t.argtypes &&
 2284                   restype == t.restype &&
 2285                   thrown == t.thrown)
 2286                   return t;
 2287               else
 2288                   return new MethodType(argtypes, restype, thrown, t.tsym);
 2289           }
 2290   
 2291           @Override
 2292           public Type visitTypeVar(TypeVar t, Void ignored) {
 2293               for (List<Type> from = this.from, to = this.to;
 2294                    from.nonEmpty();
 2295                    from = from.tail, to = to.tail) {
 2296                   if (t == from.head) {
 2297                       return to.head.withTypeVar(t);
 2298                   }
 2299               }
 2300               return t;
 2301           }
 2302   
 2303           @Override
 2304           public Type visitClassType(ClassType t, Void ignored) {
 2305               if (!t.isCompound()) {
 2306                   List<Type> typarams = t.getTypeArguments();
 2307                   List<Type> typarams1 = subst(typarams);
 2308                   Type outer = t.getEnclosingType();
 2309                   Type outer1 = subst(outer);
 2310                   if (typarams1 == typarams && outer1 == outer)
 2311                       return t;
 2312                   else
 2313                       return new ClassType(outer1, typarams1, t.tsym);
 2314               } else {
 2315                   Type st = subst(supertype(t));
 2316                   List<Type> is = upperBounds(subst(interfaces(t)));
 2317                   if (st == supertype(t) && is == interfaces(t))
 2318                       return t;
 2319                   else
 2320                       return makeCompoundType(is.prepend(st));
 2321               }
 2322           }
 2323   
 2324           @Override
 2325           public Type visitWildcardType(WildcardType t, Void ignored) {
 2326               Type bound = t.type;
 2327               if (t.kind != BoundKind.UNBOUND)
 2328                   bound = subst(bound);
 2329               if (bound == t.type) {
 2330                   return t;
 2331               } else {
 2332                   if (t.isExtendsBound() && bound.isExtendsBound())
 2333                       bound = upperBound(bound);
 2334                   return new WildcardType(bound, t.kind, syms.boundClass, t.bound);
 2335               }
 2336           }
 2337   
 2338           @Override
 2339           public Type visitArrayType(ArrayType t, Void ignored) {
 2340               Type elemtype = subst(t.elemtype);
 2341               if (elemtype == t.elemtype)
 2342                   return t;
 2343               else
 2344                   return new ArrayType(upperBound(elemtype), t.tsym);
 2345           }
 2346   
 2347           @Override
 2348           public Type visitForAll(ForAll t, Void ignored) {
 2349               if (Type.containsAny(to, t.tvars)) {
 2350                   //perform alpha-renaming of free-variables in 't'
 2351                   //if 'to' types contain variables that are free in 't'
 2352                   List<Type> freevars = newInstances(t.tvars);
 2353                   t = new ForAll(freevars,
 2354                           Types.this.subst(t.qtype, t.tvars, freevars));
 2355               }
 2356               List<Type> tvars1 = substBounds(t.tvars, from, to);
 2357               Type qtype1 = subst(t.qtype);
 2358               if (tvars1 == t.tvars && qtype1 == t.qtype) {
 2359                   return t;
 2360               } else if (tvars1 == t.tvars) {
 2361                   return new ForAll(tvars1, qtype1);
 2362               } else {
 2363                   return new ForAll(tvars1, Types.this.subst(qtype1, t.tvars, tvars1));
 2364               }
 2365           }
 2366   
 2367           @Override
 2368           public Type visitErrorType(ErrorType t, Void ignored) {
 2369               return t;
 2370           }
 2371       }
 2372   
 2373       public List<Type> substBounds(List<Type> tvars,
 2374                                     List<Type> from,
 2375                                     List<Type> to) {
 2376           if (tvars.isEmpty())
 2377               return tvars;
 2378           ListBuffer<Type> newBoundsBuf = lb();
 2379           boolean changed = false;
 2380           // calculate new bounds
 2381           for (Type t : tvars) {
 2382               TypeVar tv = (TypeVar) t;
 2383               Type bound = subst(tv.bound, from, to);
 2384               if (bound != tv.bound)
 2385                   changed = true;
 2386               newBoundsBuf.append(bound);
 2387           }
 2388           if (!changed)
 2389               return tvars;
 2390           ListBuffer<Type> newTvars = lb();
 2391           // create new type variables without bounds
 2392           for (Type t : tvars) {
 2393               newTvars.append(new TypeVar(t.tsym, null, syms.botType));
 2394           }
 2395           // the new bounds should use the new type variables in place
 2396           // of the old
 2397           List<Type> newBounds = newBoundsBuf.toList();
 2398           from = tvars;
 2399           to = newTvars.toList();
 2400           for (; !newBounds.isEmpty(); newBounds = newBounds.tail) {
 2401               newBounds.head = subst(newBounds.head, from, to);
 2402           }
 2403           newBounds = newBoundsBuf.toList();
 2404           // set the bounds of new type variables to the new bounds
 2405           for (Type t : newTvars.toList()) {
 2406               TypeVar tv = (TypeVar) t;
 2407               tv.bound = newBounds.head;
 2408               newBounds = newBounds.tail;
 2409           }
 2410           return newTvars.toList();
 2411       }
 2412   
 2413       public TypeVar substBound(TypeVar t, List<Type> from, List<Type> to) {
 2414           Type bound1 = subst(t.bound, from, to);
 2415           if (bound1 == t.bound)
 2416               return t;
 2417           else {
 2418               // create new type variable without bounds
 2419               TypeVar tv = new TypeVar(t.tsym, null, syms.botType);
 2420               // the new bound should use the new type variable in place
 2421               // of the old
 2422               tv.bound = subst(bound1, List.<Type>of(t), List.<Type>of(tv));
 2423               return tv;
 2424           }
 2425       }
 2426       // </editor-fold>
 2427   
 2428       // <editor-fold defaultstate="collapsed" desc="hasSameBounds">
 2429       /**
 2430        * Does t have the same bounds for quantified variables as s?
 2431        */
 2432       boolean hasSameBounds(ForAll t, ForAll s) {
 2433           List<Type> l1 = t.tvars;
 2434           List<Type> l2 = s.tvars;
 2435           while (l1.nonEmpty() && l2.nonEmpty() &&
 2436                  isSameType(l1.head.getUpperBound(),
 2437                             subst(l2.head.getUpperBound(),
 2438                                   s.tvars,
 2439                                   t.tvars))) {
 2440               l1 = l1.tail;
 2441               l2 = l2.tail;
 2442           }
 2443           return l1.isEmpty() && l2.isEmpty();
 2444       }
 2445       // </editor-fold>
 2446   
 2447       // <editor-fold defaultstate="collapsed" desc="newInstances">
 2448       /** Create new vector of type variables from list of variables
 2449        *  changing all recursive bounds from old to new list.
 2450        */
 2451       public List<Type> newInstances(List<Type> tvars) {
 2452           List<Type> tvars1 = Type.map(tvars, newInstanceFun);
 2453           for (List<Type> l = tvars1; l.nonEmpty(); l = l.tail) {
 2454               TypeVar tv = (TypeVar) l.head;
 2455               tv.bound = subst(tv.bound, tvars, tvars1);
 2456           }
 2457           return tvars1;
 2458       }
 2459       static private Mapping newInstanceFun = new Mapping("newInstanceFun") {
 2460               public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound()); }
 2461           };
 2462       // </editor-fold>
 2463   
 2464       public Type createMethodTypeWithParameters(Type original, List<Type> newParams) {
 2465           return original.accept(methodWithParameters, newParams);
 2466       }
 2467       // where
 2468           private final MapVisitor<List<Type>> methodWithParameters = new MapVisitor<List<Type>>() {
 2469               public Type visitType(Type t, List<Type> newParams) {
 2470                   throw new IllegalArgumentException("Not a method type: " + t);
 2471               }
 2472               public Type visitMethodType(MethodType t, List<Type> newParams) {
 2473                   return new MethodType(newParams, t.restype, t.thrown, t.tsym);
 2474               }
 2475               public Type visitForAll(ForAll t, List<Type> newParams) {
 2476                   return new ForAll(t.tvars, t.qtype.accept(this, newParams));
 2477               }
 2478           };
 2479   
 2480       public Type createMethodTypeWithThrown(Type original, List<Type> newThrown) {
 2481           return original.accept(methodWithThrown, newThrown);
 2482       }
 2483       // where
 2484           private final MapVisitor<List<Type>> methodWithThrown = new MapVisitor<List<Type>>() {
 2485               public Type visitType(Type t, List<Type> newThrown) {
 2486                   throw new IllegalArgumentException("Not a method type: " + t);
 2487               }
 2488               public Type visitMethodType(MethodType t, List<Type> newThrown) {
 2489                   return new MethodType(t.argtypes, t.restype, newThrown, t.tsym);
 2490               }
 2491               public Type visitForAll(ForAll t, List<Type> newThrown) {
 2492                   return new ForAll(t.tvars, t.qtype.accept(this, newThrown));
 2493               }
 2494           };
 2495   
 2496       public Type createMethodTypeWithReturn(Type original, Type newReturn) {
 2497           return original.accept(methodWithReturn, newReturn);
 2498       }
 2499       // where
 2500           private final MapVisitor<Type> methodWithReturn = new MapVisitor<Type>() {
 2501               public Type visitType(Type t, Type newReturn) {
 2502                   throw new IllegalArgumentException("Not a method type: " + t);
 2503               }
 2504               public Type visitMethodType(MethodType t, Type newReturn) {
 2505                   return new MethodType(t.argtypes, newReturn, t.thrown, t.tsym);
 2506               }
 2507               public Type visitForAll(ForAll t, Type newReturn) {
 2508                   return new ForAll(t.tvars, t.qtype.accept(this, newReturn));
 2509               }
 2510           };
 2511   
 2512       // <editor-fold defaultstate="collapsed" desc="createErrorType">
 2513       public Type createErrorType(Type originalType) {
 2514           return new ErrorType(originalType, syms.errSymbol);
 2515       }
 2516   
 2517       public Type createErrorType(ClassSymbol c, Type originalType) {
 2518           return new ErrorType(c, originalType);
 2519       }
 2520   
 2521       public Type createErrorType(Name name, TypeSymbol container, Type originalType) {
 2522           return new ErrorType(name, container, originalType);
 2523       }
 2524       // </editor-fold>
 2525   
 2526       // <editor-fold defaultstate="collapsed" desc="rank">
 2527       /**
 2528        * The rank of a class is the length of the longest path between
 2529        * the class and java.lang.Object in the class inheritance
 2530        * graph. Undefined for all but reference types.
 2531        */
 2532       public int rank(Type t) {
 2533           switch(t.tag) {
 2534           case CLASS: {
 2535               ClassType cls = (ClassType)t;
 2536               if (cls.rank_field < 0) {
 2537                   Name fullname = cls.tsym.getQualifiedName();
 2538                   if (fullname == names.java_lang_Object)
 2539                       cls.rank_field = 0;
 2540                   else {
 2541                       int r = rank(supertype(cls));
 2542                       for (List<Type> l = interfaces(cls);
 2543                            l.nonEmpty();
 2544                            l = l.tail) {
 2545                           if (rank(l.head) > r)
 2546                               r = rank(l.head);
 2547                       }
 2548                       cls.rank_field = r + 1;
 2549                   }
 2550               }
 2551               return cls.rank_field;
 2552           }
 2553           case TYPEVAR: {
 2554               TypeVar tvar = (TypeVar)t;
 2555               if (tvar.rank_field < 0) {
 2556                   int r = rank(supertype(tvar));
 2557                   for (List<Type> l = interfaces(tvar);
 2558                        l.nonEmpty();
 2559                        l = l.tail) {
 2560                       if (rank(l.head) > r) r = rank(l.head);
 2561                   }
 2562                   tvar.rank_field = r + 1;
 2563               }
 2564               return tvar.rank_field;
 2565           }
 2566           case ERROR:
 2567               return 0;
 2568           default:
 2569               throw new AssertionError();
 2570           }
 2571       }
 2572       // </editor-fold>
 2573   
 2574       /**
 2575        * Helper method for generating a string representation of a given type
 2576        * accordingly to a given locale
 2577        */
 2578       public String toString(Type t, Locale locale) {
 2579           return Printer.createStandardPrinter(messages).visit(t, locale);
 2580       }
 2581   
 2582       /**
 2583        * Helper method for generating a string representation of a given type
 2584        * accordingly to a given locale
 2585        */
 2586       public String toString(Symbol t, Locale locale) {
 2587           return Printer.createStandardPrinter(messages).visit(t, locale);
 2588       }
 2589   
 2590       // <editor-fold defaultstate="collapsed" desc="toString">
 2591       /**
 2592        * This toString is slightly more descriptive than the one on Type.
 2593        *
 2594        * @deprecated Types.toString(Type t, Locale l) provides better support
 2595        * for localization
 2596        */
 2597       @Deprecated
 2598       public String toString(Type t) {
 2599           if (t.tag == FORALL) {
 2600               ForAll forAll = (ForAll)t;
 2601               return typaramsString(forAll.tvars) + forAll.qtype;
 2602           }
 2603           return "" + t;
 2604       }
 2605       // where
 2606           private String typaramsString(List<Type> tvars) {
 2607               StringBuilder s = new StringBuilder();
 2608               s.append('<');
 2609               boolean first = true;
 2610               for (Type t : tvars) {
 2611                   if (!first) s.append(", ");
 2612                   first = false;
 2613                   appendTyparamString(((TypeVar)t), s);
 2614               }
 2615               s.append('>');
 2616               return s.toString();
 2617           }
 2618           private void appendTyparamString(TypeVar t, StringBuilder buf) {
 2619               buf.append(t);
 2620               if (t.bound == null ||
 2621                   t.bound.tsym.getQualifiedName() == names.java_lang_Object)
 2622                   return;
 2623               buf.append(" extends "); // Java syntax; no need for i18n
 2624               Type bound = t.bound;
 2625               if (!bound.isCompound()) {
 2626                   buf.append(bound);
 2627               } else if ((erasure(t).tsym.flags() & INTERFACE) == 0) {
 2628                   buf.append(supertype(t));
 2629                   for (Type intf : interfaces(t)) {
 2630                       buf.append('&');
 2631                       buf.append(intf);
 2632                   }
 2633               } else {
 2634                   // No superclass was given in bounds.
 2635                   // In this case, supertype is Object, erasure is first interface.
 2636                   boolean first = true;
 2637                   for (Type intf : interfaces(t)) {
 2638                       if (!first) buf.append('&');
 2639                       first = false;
 2640                       buf.append(intf);
 2641                   }
 2642               }
 2643           }
 2644       // </editor-fold>
 2645   
 2646       // <editor-fold defaultstate="collapsed" desc="Determining least upper bounds of types">
 2647       /**
 2648        * A cache for closures.
 2649        *
 2650        * <p>A closure is a list of all the supertypes and interfaces of
 2651        * a class or interface type, ordered by ClassSymbol.precedes
 2652        * (that is, subclasses come first, arbitrary but fixed
 2653        * otherwise).
 2654        */
 2655       private Map<Type,List<Type>> closureCache = new HashMap<Type,List<Type>>();
 2656   
 2657       /**
 2658        * Returns the closure of a class or interface type.
 2659        */
 2660       public List<Type> closure(Type t) {
 2661           List<Type> cl = closureCache.get(t);
 2662           if (cl == null) {
 2663               Type st = supertype(t);
 2664               if (!t.isCompound()) {
 2665                   if (st.tag == CLASS) {
 2666                       cl = insert(closure(st), t);
 2667                   } else if (st.tag == TYPEVAR) {
 2668                       cl = closure(st).prepend(t);
 2669                   } else {
 2670                       cl = List.of(t);
 2671                   }
 2672               } else {
 2673                   cl = closure(supertype(t));
 2674               }
 2675               for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail)
 2676                   cl = union(cl, closure(l.head));
 2677               closureCache.put(t, cl);
 2678           }
 2679           return cl;
 2680       }
 2681   
 2682       /**
 2683        * Insert a type in a closure
 2684        */
 2685       public List<Type> insert(List<Type> cl, Type t) {
 2686           if (cl.isEmpty() || t.tsym.precedes(cl.head.tsym, this)) {
 2687               return cl.prepend(t);
 2688           } else if (cl.head.tsym.precedes(t.tsym, this)) {
 2689               return insert(cl.tail, t).prepend(cl.head);
 2690           } else {
 2691               return cl;
 2692           }
 2693       }
 2694   
 2695       /**
 2696        * Form the union of two closures
 2697        */
 2698       public List<Type> union(List<Type> cl1, List<Type> cl2) {
 2699           if (cl1.isEmpty()) {
 2700               return cl2;
 2701           } else if (cl2.isEmpty()) {
 2702               return cl1;
 2703           } else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) {
 2704               return union(cl1.tail, cl2).prepend(cl1.head);
 2705           } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) {
 2706               return union(cl1, cl2.tail).prepend(cl2.head);
 2707           } else {
 2708               return union(cl1.tail, cl2.tail).prepend(cl1.head);
 2709           }
 2710       }
 2711   
 2712       /**
 2713        * Intersect two closures
 2714        */
 2715       public List<Type> intersect(List<Type> cl1, List<Type> cl2) {
 2716           if (cl1 == cl2)
 2717               return cl1;
 2718           if (cl1.isEmpty() || cl2.isEmpty())
 2719               return List.nil();
 2720           if (cl1.head.tsym.precedes(cl2.head.tsym, this))
 2721               return intersect(cl1.tail, cl2);
 2722           if (cl2.head.tsym.precedes(cl1.head.tsym, this))
 2723               return intersect(cl1, cl2.tail);
 2724           if (isSameType(cl1.head, cl2.head))
 2725               return intersect(cl1.tail, cl2.tail).prepend(cl1.head);
 2726           if (cl1.head.tsym == cl2.head.tsym &&
 2727               cl1.head.tag == CLASS && cl2.head.tag == CLASS) {
 2728               if (cl1.head.isParameterized() && cl2.head.isParameterized()) {
 2729                   Type merge = merge(cl1.head,cl2.head);
 2730                   return intersect(cl1.tail, cl2.tail).prepend(merge);
 2731               }
 2732               if (cl1.head.isRaw() || cl2.head.isRaw())
 2733                   return intersect(cl1.tail, cl2.tail).prepend(erasure(cl1.head));
 2734           }
 2735           return intersect(cl1.tail, cl2.tail);
 2736       }
 2737       // where
 2738           class TypePair {
 2739               final Type t1;
 2740               final Type t2;
 2741               TypePair(Type t1, Type t2) {
 2742                   this.t1 = t1;
 2743                   this.t2 = t2;
 2744               }
 2745               @Override
 2746               public int hashCode() {
 2747                   return 127 * Types.hashCode(t1) + Types.hashCode(t2);
 2748               }
 2749               @Override
 2750               public boolean equals(Object obj) {
 2751                   if (!(obj instanceof TypePair))
 2752                       return false;
 2753                   TypePair typePair = (TypePair)obj;
 2754                   return isSameType(t1, typePair.t1)
 2755                       && isSameType(t2, typePair.t2);
 2756               }
 2757           }
 2758           Set<TypePair> mergeCache = new HashSet<TypePair>();
 2759           private Type merge(Type c1, Type c2) {
 2760               ClassType class1 = (ClassType) c1;
 2761               List<Type> act1 = class1.getTypeArguments();
 2762               ClassType class2 = (ClassType) c2;
 2763               List<Type> act2 = class2.getTypeArguments();
 2764               ListBuffer<Type> merged = new ListBuffer<Type>();
 2765               List<Type> typarams = class1.tsym.type.getTypeArguments();
 2766   
 2767               while (act1.nonEmpty() && act2.nonEmpty() && typarams.nonEmpty()) {
 2768                   if (containsType(act1.head, act2.head)) {
 2769                       merged.append(act1.head);
 2770                   } else if (containsType(act2.head, act1.head)) {
 2771                       merged.append(act2.head);
 2772                   } else {
 2773                       TypePair pair = new TypePair(c1, c2);
 2774                       Type m;
 2775                       if (mergeCache.add(pair)) {
 2776                           m = new WildcardType(lub(upperBound(act1.head),
 2777                                                    upperBound(act2.head)),
 2778                                                BoundKind.EXTENDS,
 2779                                                syms.boundClass);
 2780                           mergeCache.remove(pair);
 2781                       } else {
 2782                           m = new WildcardType(syms.objectType,
 2783                                                BoundKind.UNBOUND,
 2784                                                syms.boundClass);
 2785                       }
 2786                       merged.append(m.withTypeVar(typarams.head));
 2787                   }
 2788                   act1 = act1.tail;
 2789                   act2 = act2.tail;
 2790                   typarams = typarams.tail;
 2791               }
 2792               Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
 2793               return new ClassType(class1.getEnclosingType(), merged.toList(), class1.tsym);
 2794           }
 2795   
 2796       /**
 2797        * Return the minimum type of a closure, a compound type if no
 2798        * unique minimum exists.
 2799        */
 2800       private Type compoundMin(List<Type> cl) {
 2801           if (cl.isEmpty()) return syms.objectType;
 2802           List<Type> compound = closureMin(cl);
 2803           if (compound.isEmpty())
 2804               return null;
 2805           else if (compound.tail.isEmpty())
 2806               return compound.head;
 2807           else
 2808               return makeCompoundType(compound);
 2809       }
 2810   
 2811       /**
 2812        * Return the minimum types of a closure, suitable for computing
 2813        * compoundMin or glb.
 2814        */
 2815       private List<Type> closureMin(List<Type> cl) {
 2816           ListBuffer<Type> classes = lb();
 2817           ListBuffer<Type> interfaces = lb();
 2818           while (!cl.isEmpty()) {
 2819               Type current = cl.head;
 2820               if (current.isInterface())
 2821                   interfaces.append(current);
 2822               else
 2823                   classes.append(current);
 2824               ListBuffer<Type> candidates = lb();
 2825               for (Type t : cl.tail) {
 2826                   if (!isSubtypeNoCapture(current, t))
 2827                       candidates.append(t);
 2828               }
 2829               cl = candidates.toList();
 2830           }
 2831           return classes.appendList(interfaces).toList();
 2832       }
 2833   
 2834       /**
 2835        * Return the least upper bound of pair of types.  if the lub does
 2836        * not exist return null.
 2837        */
 2838       public Type lub(Type t1, Type t2) {
 2839           return lub(List.of(t1, t2));
 2840       }
 2841   
 2842       /**
 2843        * Return the least upper bound (lub) of set of types.  If the lub
 2844        * does not exist return the type of null (bottom).
 2845        */
 2846       public Type lub(List<Type> ts) {
 2847           final int ARRAY_BOUND = 1;
 2848           final int CLASS_BOUND = 2;
 2849           int boundkind = 0;
 2850           for (Type t : ts) {
 2851               switch (t.tag) {
 2852               case CLASS:
 2853                   boundkind |= CLASS_BOUND;
 2854                   break;
 2855               case ARRAY:
 2856                   boundkind |= ARRAY_BOUND;
 2857                   break;
 2858               case  TYPEVAR:
 2859                   do {
 2860                       t = t.getUpperBound();
 2861                   } while (t.tag == TYPEVAR);
 2862                   if (t.tag == ARRAY) {
 2863                       boundkind |= ARRAY_BOUND;
 2864                   } else {
 2865                       boundkind |= CLASS_BOUND;
 2866                   }
 2867                   break;
 2868               default:
 2869                   if (t.isPrimitive())
 2870                       return syms.errType;
 2871               }
 2872           }
 2873           switch (boundkind) {
 2874           case 0:
 2875               return syms.botType;
 2876   
 2877           case ARRAY_BOUND:
 2878               // calculate lub(A[], B[])
 2879               List<Type> elements = Type.map(ts, elemTypeFun);
 2880               for (Type t : elements) {
 2881                   if (t.isPrimitive()) {
 2882                       // if a primitive type is found, then return
 2883                       // arraySuperType unless all the types are the
 2884                       // same
 2885                       Type first = ts.head;
 2886                       for (Type s : ts.tail) {
 2887                           if (!isSameType(first, s)) {
 2888                                // lub(int[], B[]) is Cloneable & Serializable
 2889                               return arraySuperType();
 2890                           }
 2891                       }
 2892                       // all the array types are the same, return one
 2893                       // lub(int[], int[]) is int[]
 2894                       return first;
 2895                   }
 2896               }
 2897               // lub(A[], B[]) is lub(A, B)[]
 2898               return new ArrayType(lub(elements), syms.arrayClass);
 2899   
 2900           case CLASS_BOUND:
 2901               // calculate lub(A, B)
 2902               while (ts.head.tag != CLASS && ts.head.tag != TYPEVAR)
 2903                   ts = ts.tail;
 2904               Assert.check(!ts.isEmpty());
 2905               //step 1 - compute erased candidate set (EC)
 2906               List<Type> cl = erasedSupertypes(ts.head);
 2907               for (Type t : ts.tail) {
 2908                   if (t.tag == CLASS || t.tag == TYPEVAR)
 2909                       cl = intersect(cl, erasedSupertypes(t));
 2910               }
 2911               //step 2 - compute minimal erased candidate set (MEC)
 2912               List<Type> mec = closureMin(cl);
 2913               //step 3 - for each element G in MEC, compute lci(Inv(G))
 2914               List<Type> candidates = List.nil();
 2915               for (Type erasedSupertype : mec) {
 2916                   List<Type> lci = List.of(asSuper(ts.head, erasedSupertype.tsym));
 2917                   for (Type t : ts) {
 2918                       lci = intersect(lci, List.of(asSuper(t, erasedSupertype.tsym)));
 2919                   }
 2920                   candidates = candidates.appendList(lci);
 2921               }
 2922               //step 4 - let MEC be { G1, G2 ... Gn }, then we have that
 2923               //lub = lci(Inv(G1)) & lci(Inv(G2)) & ... & lci(Inv(Gn))
 2924               return compoundMin(candidates);
 2925   
 2926           default:
 2927               // calculate lub(A, B[])
 2928               List<Type> classes = List.of(arraySuperType());
 2929               for (Type t : ts) {
 2930                   if (t.tag != ARRAY) // Filter out any arrays
 2931                       classes = classes.prepend(t);
 2932               }
 2933               // lub(A, B[]) is lub(A, arraySuperType)
 2934               return lub(classes);
 2935           }
 2936       }
 2937       // where
 2938           List<Type> erasedSupertypes(Type t) {
 2939               ListBuffer<Type> buf = lb();
 2940               for (Type sup : closure(t)) {
 2941                   if (sup.tag == TYPEVAR) {
 2942                       buf.append(sup);
 2943                   } else {
 2944                       buf.append(erasure(sup));
 2945                   }
 2946               }
 2947               return buf.toList();
 2948           }
 2949   
 2950           private Type arraySuperType = null;
 2951           private Type arraySuperType() {
 2952               // initialized lazily to avoid problems during compiler startup
 2953               if (arraySuperType == null) {
 2954                   synchronized (this) {
 2955                       if (arraySuperType == null) {
 2956                           // JLS 10.8: all arrays implement Cloneable and Serializable.
 2957                           arraySuperType = makeCompoundType(List.of(syms.serializableType,
 2958                                                                     syms.cloneableType),
 2959                                                             syms.objectType);
 2960                       }
 2961                   }
 2962               }
 2963               return arraySuperType;
 2964           }
 2965       // </editor-fold>
 2966   
 2967       // <editor-fold defaultstate="collapsed" desc="Greatest lower bound">
 2968       public Type glb(List<Type> ts) {
 2969           Type t1 = ts.head;
 2970           for (Type t2 : ts.tail) {
 2971               if (t1.isErroneous())
 2972                   return t1;
 2973               t1 = glb(t1, t2);
 2974           }
 2975           return t1;
 2976       }
 2977       //where
 2978       public Type glb(Type t, Type s) {
 2979           if (s == null)
 2980               return t;
 2981           else if (t.isPrimitive() || s.isPrimitive())
 2982               return syms.errType;
 2983           else if (isSubtypeNoCapture(t, s))
 2984               return t;
 2985           else if (isSubtypeNoCapture(s, t))
 2986               return s;
 2987   
 2988           List<Type> closure = union(closure(t), closure(s));
 2989           List<Type> bounds = closureMin(closure);
 2990   
 2991           if (bounds.isEmpty()) {             // length == 0
 2992               return syms.objectType;
 2993           } else if (bounds.tail.isEmpty()) { // length == 1
 2994               return bounds.head;
 2995           } else {                            // length > 1
 2996               int classCount = 0;
 2997               for (Type bound : bounds)
 2998                   if (!bound.isInterface())
 2999                       classCount++;
 3000               if (classCount > 1)
 3001                   return createErrorType(t);
 3002           }
 3003           return makeCompoundType(bounds);
 3004       }
 3005       // </editor-fold>
 3006   
 3007       // <editor-fold defaultstate="collapsed" desc="hashCode">
 3008       /**
 3009        * Compute a hash code on a type.
 3010        */
 3011       public static int hashCode(Type t) {
 3012           return hashCode.visit(t);
 3013       }
 3014       // where
 3015           private static final UnaryVisitor<Integer> hashCode = new UnaryVisitor<Integer>() {
 3016   
 3017               public Integer visitType(Type t, Void ignored) {
 3018                   return t.tag;
 3019               }
 3020   
 3021               @Override
 3022               public Integer visitClassType(ClassType t, Void ignored) {
 3023                   int result = visit(t.getEnclosingType());
 3024                   result *= 127;
 3025                   result += t.tsym.flatName().hashCode();
 3026                   for (Type s : t.getTypeArguments()) {
 3027                       result *= 127;
 3028                       result += visit(s);
 3029                   }
 3030                   return result;
 3031               }
 3032   
 3033               @Override
 3034               public Integer visitWildcardType(WildcardType t, Void ignored) {
 3035                   int result = t.kind.hashCode();
 3036                   if (t.type != null) {
 3037                       result *= 127;
 3038                       result += visit(t.type);
 3039                   }
 3040                   return result;
 3041               }
 3042   
 3043               @Override
 3044               public Integer visitArrayType(ArrayType t, Void ignored) {
 3045                   return visit(t.elemtype) + 12;
 3046               }
 3047   
 3048               @Override
 3049               public Integer visitTypeVar(TypeVar t, Void ignored) {
 3050                   return System.identityHashCode(t.tsym);
 3051               }
 3052   
 3053               @Override
 3054               public Integer visitUndetVar(UndetVar t, Void ignored) {
 3055                   return System.identityHashCode(t);
 3056               }
 3057   
 3058               @Override
 3059               public Integer visitErrorType(ErrorType t, Void ignored) {
 3060                   return 0;
 3061               }
 3062           };
 3063       // </editor-fold>
 3064   
 3065       // <editor-fold defaultstate="collapsed" desc="Return-Type-Substitutable">
 3066       /**
 3067        * Does t have a result that is a subtype of the result type of s,
 3068        * suitable for covariant returns?  It is assumed that both types
 3069        * are (possibly polymorphic) method types.  Monomorphic method
 3070        * types are handled in the obvious way.  Polymorphic method types
 3071        * require renaming all type variables of one to corresponding
 3072        * type variables in the other, where correspondence is by
 3073        * position in the type parameter list. */
 3074       public boolean resultSubtype(Type t, Type s, Warner warner) {
 3075           List<Type> tvars = t.getTypeArguments();
 3076           List<Type> svars = s.getTypeArguments();
 3077           Type tres = t.getReturnType();
 3078           Type sres = subst(s.getReturnType(), svars, tvars);
 3079           return covariantReturnType(tres, sres, warner);
 3080       }
 3081   
 3082       /**
 3083        * Return-Type-Substitutable.
 3084        * @jls section 8.4.5
 3085        */
 3086       public boolean returnTypeSubstitutable(Type r1, Type r2) {
 3087           if (hasSameArgs(r1, r2))
 3088               return resultSubtype(r1, r2, Warner.noWarnings);
 3089           else
 3090               return covariantReturnType(r1.getReturnType(),
 3091                                          erasure(r2.getReturnType()),
 3092                                          Warner.noWarnings);
 3093       }
 3094   
 3095       public boolean returnTypeSubstitutable(Type r1,
 3096                                              Type r2, Type r2res,
 3097                                              Warner warner) {
 3098           if (isSameType(r1.getReturnType(), r2res))
 3099               return true;
 3100           if (r1.getReturnType().isPrimitive() || r2res.isPrimitive())
 3101               return false;
 3102   
 3103           if (hasSameArgs(r1, r2))
 3104               return covariantReturnType(r1.getReturnType(), r2res, warner);
 3105           if (!allowCovariantReturns)
 3106               return false;
 3107           if (isSubtypeUnchecked(r1.getReturnType(), r2res, warner))
 3108               return true;
 3109           if (!isSubtype(r1.getReturnType(), erasure(r2res)))
 3110               return false;
 3111           warner.warn(LintCategory.UNCHECKED);
 3112           return true;
 3113       }
 3114   
 3115       /**
 3116        * Is t an appropriate return type in an overrider for a
 3117        * method that returns s?
 3118        */
 3119       public boolean covariantReturnType(Type t, Type s, Warner warner) {
 3120           return
 3121               isSameType(t, s) ||
 3122               allowCovariantReturns &&
 3123               !t.isPrimitive() &&
 3124               !s.isPrimitive() &&
 3125               isAssignable(t, s, warner);
 3126       }
 3127       // </editor-fold>
 3128   
 3129       // <editor-fold defaultstate="collapsed" desc="Box/unbox support">
 3130       /**
 3131        * Return the class that boxes the given primitive.
 3132        */
 3133       public ClassSymbol boxedClass(Type t) {
 3134           return reader.enterClass(syms.boxedName[t.tag]);
 3135       }
 3136   
 3137       /**
 3138        * Return the boxed type if 't' is primitive, otherwise return 't' itself.
 3139        */
 3140       public Type boxedTypeOrType(Type t) {
 3141           return t.isPrimitive() ?
 3142               boxedClass(t).type :
 3143               t;
 3144       }
 3145   
 3146       /**
 3147        * Return the primitive type corresponding to a boxed type.
 3148        */
 3149       public Type unboxedType(Type t) {
 3150           if (allowBoxing) {
 3151               for (int i=0; i<syms.boxedName.length; i++) {
 3152                   Name box = syms.boxedName[i];
 3153                   if (box != null &&
 3154                       asSuper(t, reader.enterClass(box)) != null)
 3155                       return syms.typeOfTag[i];
 3156               }
 3157           }
 3158           return Type.noType;
 3159       }
 3160       // </editor-fold>
 3161   
 3162       // <editor-fold defaultstate="collapsed" desc="Capture conversion">
 3163       /*
 3164        * JLS 5.1.10 Capture Conversion:
 3165        *
 3166        * Let G name a generic type declaration with n formal type
 3167        * parameters A1 ... An with corresponding bounds U1 ... Un. There
 3168        * exists a capture conversion from G<T1 ... Tn> to G<S1 ... Sn>,
 3169        * where, for 1 <= i <= n:
 3170        *
 3171        * + If Ti is a wildcard type argument (4.5.1) of the form ? then
 3172        *   Si is a fresh type variable whose upper bound is
 3173        *   Ui[A1 := S1, ..., An := Sn] and whose lower bound is the null
 3174        *   type.
 3175        *
 3176        * + If Ti is a wildcard type argument of the form ? extends Bi,
 3177        *   then Si is a fresh type variable whose upper bound is
 3178        *   glb(Bi, Ui[A1 := S1, ..., An := Sn]) and whose lower bound is
 3179        *   the null type, where glb(V1,... ,Vm) is V1 & ... & Vm. It is
 3180        *   a compile-time error if for any two classes (not interfaces)
 3181        *   Vi and Vj,Vi is not a subclass of Vj or vice versa.
 3182        *
 3183        * + If Ti is a wildcard type argument of the form ? super Bi,
 3184        *   then Si is a fresh type variable whose upper bound is
 3185        *   Ui[A1 := S1, ..., An := Sn] and whose lower bound is Bi.
 3186        *
 3187        * + Otherwise, Si = Ti.
 3188        *
 3189        * Capture conversion on any type other than a parameterized type
 3190        * (4.5) acts as an identity conversion (5.1.1). Capture
 3191        * conversions never require a special action at run time and
 3192        * therefore never throw an exception at run time.
 3193        *
 3194        * Capture conversion is not applied recursively.
 3195        */
 3196       /**
 3197        * Capture conversion as specified by the JLS.
 3198        */
 3199   
 3200       public List<Type> capture(List<Type> ts) {
 3201           List<Type> buf = List.nil();
 3202           for (Type t : ts) {
 3203               buf = buf.prepend(capture(t));
 3204           }
 3205           return buf.reverse();
 3206       }
 3207       public Type capture(Type t) {
 3208           if (t.tag != CLASS)
 3209               return t;
 3210           if (t.getEnclosingType() != Type.noType) {
 3211               Type capturedEncl = capture(t.getEnclosingType());
 3212               if (capturedEncl != t.getEnclosingType()) {
 3213                   Type type1 = memberType(capturedEncl, t.tsym);
 3214                   t = subst(type1, t.tsym.type.getTypeArguments(), t.getTypeArguments());
 3215               }
 3216           }
 3217           ClassType cls = (ClassType)t;
 3218           if (cls.isRaw() || !cls.isParameterized())
 3219               return cls;
 3220   
 3221           ClassType G = (ClassType)cls.asElement().asType();
 3222           List<Type> A = G.getTypeArguments();
 3223           List<Type> T = cls.getTypeArguments();
 3224           List<Type> S = freshTypeVariables(T);
 3225   
 3226           List<Type> currentA = A;
 3227           List<Type> currentT = T;
 3228           List<Type> currentS = S;
 3229           boolean captured = false;
 3230           while (!currentA.isEmpty() &&
 3231                  !currentT.isEmpty() &&
 3232                  !currentS.isEmpty()) {
 3233               if (currentS.head != currentT.head) {
 3234                   captured = true;
 3235                   WildcardType Ti = (WildcardType)currentT.head;
 3236                   Type Ui = currentA.head.getUpperBound();
 3237                   CapturedType Si = (CapturedType)currentS.head;
 3238                   if (Ui == null)
 3239                       Ui = syms.objectType;
 3240                   switch (Ti.kind) {
 3241                   case UNBOUND:
 3242                       Si.bound = subst(Ui, A, S);
 3243                       Si.lower = syms.botType;
 3244                       break;
 3245                   case EXTENDS:
 3246                       Si.bound = glb(Ti.getExtendsBound(), subst(Ui, A, S));
 3247                       Si.lower = syms.botType;
 3248                       break;
 3249                   case SUPER:
 3250                       Si.bound = subst(Ui, A, S);
 3251                       Si.lower = Ti.getSuperBound();
 3252                       break;
 3253                   }
 3254                   if (Si.bound == Si.lower)
 3255                       currentS.head = Si.bound;
 3256               }
 3257               currentA = currentA.tail;
 3258               currentT = currentT.tail;
 3259               currentS = currentS.tail;
 3260           }
 3261           if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty())
 3262               return erasure(t); // some "rare" type involved
 3263   
 3264           if (captured)
 3265               return new ClassType(cls.getEnclosingType(), S, cls.tsym);
 3266           else
 3267               return t;
 3268       }
 3269       // where
 3270           public List<Type> freshTypeVariables(List<Type> types) {
 3271               ListBuffer<Type> result = lb();
 3272               for (Type t : types) {
 3273                   if (t.tag == WILDCARD) {
 3274                       Type bound = ((WildcardType)t).getExtendsBound();
 3275                       if (bound == null)
 3276                           bound = syms.objectType;
 3277                       result.append(new CapturedType(capturedName,
 3278                                                      syms.noSymbol,
 3279                                                      bound,
 3280                                                      syms.botType,
 3281                                                      (WildcardType)t));
 3282                   } else {
 3283                       result.append(t);
 3284                   }
 3285               }
 3286               return result.toList();
 3287           }
 3288       // </editor-fold>
 3289   
 3290       // <editor-fold defaultstate="collapsed" desc="Internal utility methods">
 3291       private List<Type> upperBounds(List<Type> ss) {
 3292           if (ss.isEmpty()) return ss;
 3293           Type head = upperBound(ss.head);
 3294           List<Type> tail = upperBounds(ss.tail);
 3295           if (head != ss.head || tail != ss.tail)
 3296               return tail.prepend(head);
 3297           else
 3298               return ss;
 3299       }
 3300   
 3301       private boolean sideCast(Type from, Type to, Warner warn) {
 3302           // We are casting from type $from$ to type $to$, which are
 3303           // non-final unrelated types.  This method
 3304           // tries to reject a cast by transferring type parameters
 3305           // from $to$ to $from$ by common superinterfaces.
 3306           boolean reverse = false;
 3307           Type target = to;
 3308           if ((to.tsym.flags() & INTERFACE) == 0) {
 3309               Assert.check((from.tsym.flags() & INTERFACE) != 0);
 3310               reverse = true;
 3311               to = from;
 3312               from = target;
 3313           }
 3314           List<Type> commonSupers = superClosure(to, erasure(from));
 3315           boolean giveWarning = commonSupers.isEmpty();
 3316           // The arguments to the supers could be unified here to
 3317           // get a more accurate analysis
 3318           while (commonSupers.nonEmpty()) {
 3319               Type t1 = asSuper(from, commonSupers.head.tsym);
 3320               Type t2 = commonSupers.head; // same as asSuper(to, commonSupers.head.tsym);
 3321               if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
 3322                   return false;
 3323               giveWarning = giveWarning || (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2));
 3324               commonSupers = commonSupers.tail;
 3325           }
 3326           if (giveWarning && !isReifiable(reverse ? from : to))
 3327               warn.warn(LintCategory.UNCHECKED);
 3328           if (!allowCovariantReturns)
 3329               // reject if there is a common method signature with
 3330               // incompatible return types.
 3331               chk.checkCompatibleAbstracts(warn.pos(), from, to);
 3332           return true;
 3333       }
 3334   
 3335       private boolean sideCastFinal(Type from, Type to, Warner warn) {
 3336           // We are casting from type $from$ to type $to$, which are
 3337           // unrelated types one of which is final and the other of
 3338           // which is an interface.  This method
 3339           // tries to reject a cast by transferring type parameters
 3340           // from the final class to the interface.
 3341           boolean reverse = false;
 3342           Type target = to;
 3343           if ((to.tsym.flags() & INTERFACE) == 0) {
 3344               Assert.check((from.tsym.flags() & INTERFACE) != 0);
 3345               reverse = true;
 3346               to = from;
 3347               from = target;
 3348           }
 3349           Assert.check((from.tsym.flags() & FINAL) != 0);
 3350           Type t1 = asSuper(from, to.tsym);
 3351           if (t1 == null) return false;
 3352           Type t2 = to;
 3353           if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
 3354               return false;
 3355           if (!allowCovariantReturns)
 3356               // reject if there is a common method signature with
 3357               // incompatible return types.
 3358               chk.checkCompatibleAbstracts(warn.pos(), from, to);
 3359           if (!isReifiable(target) &&
 3360               (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2)))
 3361               warn.warn(LintCategory.UNCHECKED);
 3362           return true;
 3363       }
 3364   
 3365       private boolean giveWarning(Type from, Type to) {
 3366           Type subFrom = asSub(from, to.tsym);
 3367           return to.isParameterized() &&
 3368                   (!(isUnbounded(to) ||
 3369                   isSubtype(from, to) ||
 3370                   ((subFrom != null) && containsType(to.allparams(), subFrom.allparams()))));
 3371       }
 3372   
 3373       private List<Type> superClosure(Type t, Type s) {
 3374           List<Type> cl = List.nil();
 3375           for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
 3376               if (isSubtype(s, erasure(l.head))) {
 3377                   cl = insert(cl, l.head);
 3378               } else {
 3379                   cl = union(cl, superClosure(l.head, s));
 3380               }
 3381           }
 3382           return cl;
 3383       }
 3384   
 3385       private boolean containsTypeEquivalent(Type t, Type s) {
 3386           return
 3387               isSameType(t, s) || // shortcut
 3388               containsType(t, s) && containsType(s, t);
 3389       }
 3390   
 3391       // <editor-fold defaultstate="collapsed" desc="adapt">
 3392       /**
 3393        * Adapt a type by computing a substitution which maps a source
 3394        * type to a target type.
 3395        *
 3396        * @param source    the source type
 3397        * @param target    the target type
 3398        * @param from      the type variables of the computed substitution
 3399        * @param to        the types of the computed substitution.
 3400        */
 3401       public void adapt(Type source,
 3402                          Type target,
 3403                          ListBuffer<Type> from,
 3404                          ListBuffer<Type> to) throws AdaptFailure {
 3405           new Adapter(from, to).adapt(source, target);
 3406       }
 3407   
 3408       class Adapter extends SimpleVisitor<Void, Type> {
 3409   
 3410           ListBuffer<Type> from;
 3411           ListBuffer<Type> to;
 3412           Map<Symbol,Type> mapping;
 3413   
 3414           Adapter(ListBuffer<Type> from, ListBuffer<Type> to) {
 3415               this.from = from;
 3416               this.to = to;
 3417               mapping = new HashMap<Symbol,Type>();
 3418           }
 3419   
 3420           public void adapt(Type source, Type target) throws AdaptFailure {
 3421               visit(source, target);
 3422               List<Type> fromList = from.toList();
 3423               List<Type> toList = to.toList();
 3424               while (!fromList.isEmpty()) {
 3425                   Type val = mapping.get(fromList.head.tsym);
 3426                   if (toList.head != val)
 3427                       toList.head = val;
 3428                   fromList = fromList.tail;
 3429                   toList = toList.tail;
 3430               }
 3431           }
 3432   
 3433           @Override
 3434           public Void visitClassType(ClassType source, Type target) throws AdaptFailure {
 3435               if (target.tag == CLASS)
 3436                   adaptRecursive(source.allparams(), target.allparams());
 3437               return null;
 3438           }
 3439   
 3440           @Override
 3441           public Void visitArrayType(ArrayType source, Type target) throws AdaptFailure {
 3442               if (target.tag == ARRAY)
 3443                   adaptRecursive(elemtype(source), elemtype(target));
 3444               return null;
 3445           }
 3446   
 3447           @Override
 3448           public Void visitWildcardType(WildcardType source, Type target) throws AdaptFailure {
 3449               if (source.isExtendsBound())
 3450                   adaptRecursive(upperBound(source), upperBound(target));
 3451               else if (source.isSuperBound())
 3452                   adaptRecursive(lowerBound(source), lowerBound(target));
 3453               return null;
 3454           }
 3455   
 3456           @Override
 3457           public Void visitTypeVar(TypeVar source, Type target) throws AdaptFailure {
 3458               // Check to see if there is
 3459               // already a mapping for $source$, in which case
 3460               // the old mapping will be merged with the new
 3461               Type val = mapping.get(source.tsym);
 3462               if (val != null) {
 3463                   if (val.isSuperBound() && target.isSuperBound()) {
 3464                       val = isSubtype(lowerBound(val), lowerBound(target))
 3465                           ? target : val;
 3466                   } else if (val.isExtendsBound() && target.isExtendsBound()) {
 3467                       val = isSubtype(upperBound(val), upperBound(target))
 3468                           ? val : target;
 3469                   } else if (!isSameType(val, target)) {
 3470                       throw new AdaptFailure();
 3471                   }
 3472               } else {
 3473                   val = target;
 3474                   from.append(source);
 3475                   to.append(target);
 3476               }
 3477               mapping.put(source.tsym, val);
 3478               return null;
 3479           }
 3480   
 3481           @Override
 3482           public Void visitType(Type source, Type target) {
 3483               return null;
 3484           }
 3485   
 3486           private Set<TypePair> cache = new HashSet<TypePair>();
 3487   
 3488           private void adaptRecursive(Type source, Type target) {
 3489               TypePair pair = new TypePair(source, target);
 3490               if (cache.add(pair)) {
 3491                   try {
 3492                       visit(source, target);
 3493                   } finally {
 3494                       cache.remove(pair);
 3495                   }
 3496               }
 3497           }
 3498   
 3499           private void adaptRecursive(List<Type> source, List<Type> target) {
 3500               if (source.length() == target.length()) {
 3501                   while (source.nonEmpty()) {
 3502                       adaptRecursive(source.head, target.head);
 3503                       source = source.tail;
 3504                       target = target.tail;
 3505                   }
 3506               }
 3507           }
 3508       }
 3509   
 3510       public static class AdaptFailure extends RuntimeException {
 3511           static final long serialVersionUID = -7490231548272701566L;
 3512       }
 3513   
 3514       private void adaptSelf(Type t,
 3515                              ListBuffer<Type> from,
 3516                              ListBuffer<Type> to) {
 3517           try {
 3518               //if (t.tsym.type != t)
 3519                   adapt(t.tsym.type, t, from, to);
 3520           } catch (AdaptFailure ex) {
 3521               // Adapt should never fail calculating a mapping from
 3522               // t.tsym.type to t as there can be no merge problem.
 3523               throw new AssertionError(ex);
 3524           }
 3525       }
 3526       // </editor-fold>
 3527   
 3528       /**
 3529        * Rewrite all type variables (universal quantifiers) in the given
 3530        * type to wildcards (existential quantifiers).  This is used to
 3531        * determine if a cast is allowed.  For example, if high is true
 3532        * and {@code T <: Number}, then {@code List<T>} is rewritten to
 3533        * {@code List<?  extends Number>}.  Since {@code List<Integer> <:
 3534        * List<? extends Number>} a {@code List<T>} can be cast to {@code
 3535        * List<Integer>} with a warning.
 3536        * @param t a type
 3537        * @param high if true return an upper bound; otherwise a lower
 3538        * bound
 3539        * @param rewriteTypeVars only rewrite captured wildcards if false;
 3540        * otherwise rewrite all type variables
 3541        * @return the type rewritten with wildcards (existential
 3542        * quantifiers) only
 3543        */
 3544       private Type rewriteQuantifiers(Type t, boolean high, boolean rewriteTypeVars) {
 3545           return new Rewriter(high, rewriteTypeVars).visit(t);
 3546       }
 3547   
 3548       class Rewriter extends UnaryVisitor<Type> {
 3549   
 3550           boolean high;
 3551           boolean rewriteTypeVars;
 3552   
 3553           Rewriter(boolean high, boolean rewriteTypeVars) {
 3554               this.high = high;
 3555               this.rewriteTypeVars = rewriteTypeVars;
 3556           }
 3557   
 3558           @Override
 3559           public Type visitClassType(ClassType t, Void s) {
 3560               ListBuffer<Type> rewritten = new ListBuffer<Type>();
 3561               boolean changed = false;
 3562               for (Type arg : t.allparams()) {
 3563                   Type bound = visit(arg);
 3564                   if (arg != bound) {
 3565                       changed = true;
 3566                   }
 3567                   rewritten.append(bound);
 3568               }
 3569               if (changed)
 3570                   return subst(t.tsym.type,
 3571                           t.tsym.type.allparams(),
 3572                           rewritten.toList());
 3573               else
 3574                   return t;
 3575           }
 3576   
 3577           public Type visitType(Type t, Void s) {
 3578               return high ? upperBound(t) : lowerBound(t);
 3579           }
 3580   
 3581           @Override
 3582           public Type visitCapturedType(CapturedType t, Void s) {
 3583               Type bound = visitWildcardType(t.wildcard, null);
 3584               return (bound.contains(t)) ?
 3585                       erasure(bound) :
 3586                       bound;
 3587           }
 3588   
 3589           @Override
 3590           public Type visitTypeVar(TypeVar t, Void s) {
 3591               if (rewriteTypeVars) {
 3592                   Type bound = high ?
 3593                       (t.bound.contains(t) ?
 3594                           erasure(t.bound) :
 3595                           visit(t.bound)) :
 3596                       syms.botType;
 3597                   return rewriteAsWildcardType(bound, t);
 3598               }
 3599               else
 3600                   return t;
 3601           }
 3602   
 3603           @Override
 3604           public Type visitWildcardType(WildcardType t, Void s) {
 3605               Type bound = high ? t.getExtendsBound() :
 3606                                   t.getSuperBound();
 3607               if (bound == null)
 3608               bound = high ? syms.objectType : syms.botType;
 3609               return rewriteAsWildcardType(visit(bound), t.bound);
 3610           }
 3611   
 3612           private Type rewriteAsWildcardType(Type bound, TypeVar formal) {
 3613               return high ?
 3614                   makeExtendsWildcard(B(bound), formal) :
 3615                   makeSuperWildcard(B(bound), formal);
 3616           }
 3617   
 3618           Type B(Type t) {
 3619               while (t.tag == WILDCARD) {
 3620                   WildcardType w = (WildcardType)t;
 3621                   t = high ?
 3622                       w.getExtendsBound() :
 3623                       w.getSuperBound();
 3624                   if (t == null) {
 3625                       t = high ? syms.objectType : syms.botType;
 3626                   }
 3627               }
 3628               return t;
 3629           }
 3630       }
 3631   
 3632   
 3633       /**
 3634        * Create a wildcard with the given upper (extends) bound; create
 3635        * an unbounded wildcard if bound is Object.
 3636        *
 3637        * @param bound the upper bound
 3638        * @param formal the formal type parameter that will be
 3639        * substituted by the wildcard
 3640        */
 3641       private WildcardType makeExtendsWildcard(Type bound, TypeVar formal) {
 3642           if (bound == syms.objectType) {
 3643               return new WildcardType(syms.objectType,
 3644                                       BoundKind.UNBOUND,
 3645                                       syms.boundClass,
 3646                                       formal);
 3647           } else {
 3648               return new WildcardType(bound,
 3649                                       BoundKind.EXTENDS,
 3650                                       syms.boundClass,
 3651                                       formal);
 3652           }
 3653       }
 3654   
 3655       /**
 3656        * Create a wildcard with the given lower (super) bound; create an
 3657        * unbounded wildcard if bound is bottom (type of {@code null}).
 3658        *
 3659        * @param bound the lower bound
 3660        * @param formal the formal type parameter that will be
 3661        * substituted by the wildcard
 3662        */
 3663       private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
 3664           if (bound.tag == BOT) {
 3665               return new WildcardType(syms.objectType,
 3666                                       BoundKind.UNBOUND,
 3667                                       syms.boundClass,
 3668                                       formal);
 3669           } else {
 3670               return new WildcardType(bound,
 3671                                       BoundKind.SUPER,
 3672                                       syms.boundClass,
 3673                                       formal);
 3674           }
 3675       }
 3676   
 3677       /**
 3678        * A wrapper for a type that allows use in sets.
 3679        */
 3680       class SingletonType {
 3681           final Type t;
 3682           SingletonType(Type t) {
 3683               this.t = t;
 3684           }
 3685           public int hashCode() {
 3686               return Types.hashCode(t);
 3687           }
 3688           public boolean equals(Object obj) {
 3689               return (obj instanceof SingletonType) &&
 3690                   isSameType(t, ((SingletonType)obj).t);
 3691           }
 3692           public String toString() {
 3693               return t.toString();
 3694           }
 3695       }
 3696       // </editor-fold>
 3697   
 3698       // <editor-fold defaultstate="collapsed" desc="Visitors">
 3699       /**
 3700        * A default visitor for types.  All visitor methods except
 3701        * visitType are implemented by delegating to visitType.  Concrete
 3702        * subclasses must provide an implementation of visitType and can
 3703        * override other methods as needed.
 3704        *
 3705        * @param <R> the return type of the operation implemented by this
 3706        * visitor; use Void if no return type is needed.
 3707        * @param <S> the type of the second argument (the first being the
 3708        * type itself) of the operation implemented by this visitor; use
 3709        * Void if a second argument is not needed.
 3710        */
 3711       public static abstract class DefaultTypeVisitor<R,S> implements Type.Visitor<R,S> {
 3712           final public R visit(Type t, S s)               { return t.accept(this, s); }
 3713           public R visitClassType(ClassType t, S s)       { return visitType(t, s); }
 3714           public R visitWildcardType(WildcardType t, S s) { return visitType(t, s); }
 3715           public R visitArrayType(ArrayType t, S s)       { return visitType(t, s); }
 3716           public R visitMethodType(MethodType t, S s)     { return visitType(t, s); }
 3717           public R visitPackageType(PackageType t, S s)   { return visitType(t, s); }
 3718           public R visitTypeVar(TypeVar t, S s)           { return visitType(t, s); }
 3719           public R visitCapturedType(CapturedType t, S s) { return visitType(t, s); }
 3720           public R visitForAll(ForAll t, S s)             { return visitType(t, s); }
 3721           public R visitUndetVar(UndetVar t, S s)         { return visitType(t, s); }
 3722           public R visitErrorType(ErrorType t, S s)       { return visitType(t, s); }
 3723       }
 3724   
 3725       /**
 3726        * A default visitor for symbols.  All visitor methods except
 3727        * visitSymbol are implemented by delegating to visitSymbol.  Concrete
 3728        * subclasses must provide an implementation of visitSymbol and can
 3729        * override other methods as needed.
 3730        *
 3731        * @param <R> the return type of the operation implemented by this
 3732        * visitor; use Void if no return type is needed.
 3733        * @param <S> the type of the second argument (the first being the
 3734        * symbol itself) of the operation implemented by this visitor; use
 3735        * Void if a second argument is not needed.
 3736        */
 3737       public static abstract class DefaultSymbolVisitor<R,S> implements Symbol.Visitor<R,S> {
 3738           final public R visit(Symbol s, S arg)                   { return s.accept(this, arg); }
 3739           public R visitClassSymbol(ClassSymbol s, S arg)         { return visitSymbol(s, arg); }
 3740           public R visitMethodSymbol(MethodSymbol s, S arg)       { return visitSymbol(s, arg); }
 3741           public R visitOperatorSymbol(OperatorSymbol s, S arg)   { return visitSymbol(s, arg); }
 3742           public R visitPackageSymbol(PackageSymbol s, S arg)     { return visitSymbol(s, arg); }
 3743           public R visitTypeSymbol(TypeSymbol s, S arg)           { return visitSymbol(s, arg); }
 3744           public R visitVarSymbol(VarSymbol s, S arg)             { return visitSymbol(s, arg); }
 3745       }
 3746   
 3747       /**
 3748        * A <em>simple</em> visitor for types.  This visitor is simple as
 3749        * captured wildcards, for-all types (generic methods), and
 3750        * undetermined type variables (part of inference) are hidden.
 3751        * Captured wildcards are hidden by treating them as type
 3752        * variables and the rest are hidden by visiting their qtypes.
 3753        *
 3754        * @param <R> the return type of the operation implemented by this
 3755        * visitor; use Void if no return type is needed.
 3756        * @param <S> the type of the second argument (the first being the
 3757        * type itself) of the operation implemented by this visitor; use
 3758        * Void if a second argument is not needed.
 3759        */
 3760       public static abstract class SimpleVisitor<R,S> extends DefaultTypeVisitor<R,S> {
 3761           @Override
 3762           public R visitCapturedType(CapturedType t, S s) {
 3763               return visitTypeVar(t, s);
 3764           }
 3765           @Override
 3766           public R visitForAll(ForAll t, S s) {
 3767               return visit(t.qtype, s);
 3768           }
 3769           @Override
 3770           public R visitUndetVar(UndetVar t, S s) {
 3771               return visit(t.qtype, s);
 3772           }
 3773       }
 3774   
 3775       /**
 3776        * A plain relation on types.  That is a 2-ary function on the
 3777        * form Type&nbsp;&times;&nbsp;Type&nbsp;&rarr;&nbsp;Boolean.
 3778        * <!-- In plain text: Type x Type -> Boolean -->
 3779        */
 3780       public static abstract class TypeRelation extends SimpleVisitor<Boolean,Type> {}
 3781   
 3782       /**
 3783        * A convenience visitor for implementing operations that only
 3784        * require one argument (the type itself), that is, unary
 3785        * operations.
 3786        *
 3787        * @param <R> the return type of the operation implemented by this
 3788        * visitor; use Void if no return type is needed.
 3789        */
 3790       public static abstract class UnaryVisitor<R> extends SimpleVisitor<R,Void> {
 3791           final public R visit(Type t) { return t.accept(this, null); }
 3792       }
 3793   
 3794       /**
 3795        * A visitor for implementing a mapping from types to types.  The
 3796        * default behavior of this class is to implement the identity
 3797        * mapping (mapping a type to itself).  This can be overridden in
 3798        * subclasses.
 3799        *
 3800        * @param <S> the type of the second argument (the first being the
 3801        * type itself) of this mapping; use Void if a second argument is
 3802        * not needed.
 3803        */
 3804       public static class MapVisitor<S> extends DefaultTypeVisitor<Type,S> {
 3805           final public Type visit(Type t) { return t.accept(this, null); }
 3806           public Type visitType(Type t, S s) { return t; }
 3807       }
 3808       // </editor-fold>
 3809   
 3810   
 3811       // <editor-fold defaultstate="collapsed" desc="Annotation support">
 3812   
 3813       public RetentionPolicy getRetention(Attribute.Compound a) {
 3814           RetentionPolicy vis = RetentionPolicy.CLASS; // the default
 3815           Attribute.Compound c = a.type.tsym.attribute(syms.retentionType.tsym);
 3816           if (c != null) {
 3817               Attribute value = c.member(names.value);
 3818               if (value != null && value instanceof Attribute.Enum) {
 3819                   Name levelName = ((Attribute.Enum)value).value.name;
 3820                   if (levelName == names.SOURCE) vis = RetentionPolicy.SOURCE;
 3821                   else if (levelName == names.CLASS) vis = RetentionPolicy.CLASS;
 3822                   else if (levelName == names.RUNTIME) vis = RetentionPolicy.RUNTIME;
 3823                   else ;// /* fail soft */ throw new AssertionError(levelName);
 3824               }
 3825           }
 3826           return vis;
 3827       }
 3828       // </editor-fold>
 3829   }

Save This Page
Home » openjdk-7 » com.sun.tools » javac » code » [javadoc | source]