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