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