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