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