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

Wed, 19 Mar 2014 16:44:49 +0000

author
vromero
date
Wed, 19 Mar 2014 16:44:49 +0000
changeset 2301
27a3026256cd
parent 2260
fb870c70e774
child 2382
14979dd5e034
permissions
-rw-r--r--

8034924: Incorrect inheritance of inaccessible static method
Reviewed-by: jjg, jlahoda

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

mercurial