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