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