Resolve.java revision 3199:3a6560c043d2
165543Scg/*
2137573Sru * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
365543Scg * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
465543Scg *
565543Scg * This code is free software; you can redistribute it and/or modify it
665543Scg * under the terms of the GNU General Public License version 2 only, as
765543Scg * published by the Free Software Foundation.  Oracle designates this
865543Scg * particular file as subject to the "Classpath" exception as provided
965543Scg * by Oracle in the LICENSE file that accompanied this code.
1065543Scg *
1165543Scg * This code is distributed in the hope that it will be useful, but WITHOUT
1265543Scg * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1365543Scg * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1465543Scg * version 2 for more details (a copy is included in the LICENSE file that
1565543Scg * accompanied this code).
1665543Scg *
1765543Scg * You should have received a copy of the GNU General Public License version
1865543Scg * 2 along with this work; if not, write to the Free Software Foundation,
1965543Scg * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2065543Scg *
2165543Scg * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2265543Scg * or visit www.oracle.com if you need additional information or have any
2365543Scg * questions.
2465543Scg */
2565543Scg
26137500Sjulianpackage com.sun.tools.javac.comp;
2765543Scg
2865543Scgimport com.sun.tools.javac.api.Formattable.LocalizedString;
2965543Scgimport com.sun.tools.javac.code.*;
3065543Scgimport com.sun.tools.javac.code.Scope.WriteableScope;
3165543Scgimport com.sun.tools.javac.code.Symbol.*;
3265543Scgimport com.sun.tools.javac.code.Type.*;
3365543Scgimport com.sun.tools.javac.comp.Attr.ResultInfo;
3465543Scgimport com.sun.tools.javac.comp.Check.CheckContext;
3565543Scgimport com.sun.tools.javac.comp.DeferredAttr.AttrMode;
3665543Scgimport com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
3765543Scgimport com.sun.tools.javac.comp.DeferredAttr.DeferredType;
38119853Scgimport com.sun.tools.javac.comp.Infer.FreeTypeListener;
3965543Scgimport com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
4065543Scgimport com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template;
4165543Scgimport com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind;
4265543Scgimport com.sun.tools.javac.jvm.*;
4365543Scgimport com.sun.tools.javac.main.Option;
4465543Scgimport com.sun.tools.javac.tree.*;
45137500Sjulianimport com.sun.tools.javac.tree.JCTree.*;
46137500Sjulianimport com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
47137500Sjulianimport com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
4865543Scgimport com.sun.tools.javac.util.*;
4965543Scgimport com.sun.tools.javac.util.DefinedBy.Api;
50193640Sariffimport com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
51193640Sariffimport com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
52193640Sariffimport com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
53193640Sariff
5465543Scgimport java.util.Arrays;
5565543Scgimport java.util.Collection;
56119287Simpimport java.util.EnumSet;
57119287Simpimport java.util.Iterator;
5865543Scgimport java.util.LinkedHashMap;
5965543Scgimport java.util.Map;
6065543Scgimport java.util.function.BiPredicate;
6182180Scgimport java.util.stream.Stream;
6282180Scg
6365543Scgimport javax.lang.model.element.ElementVisitor;
6465543Scg
6565543Scgimport static com.sun.tools.javac.code.Flags.*;
6665543Scgimport static com.sun.tools.javac.code.Flags.BLOCK;
6765543Scgimport static com.sun.tools.javac.code.Flags.STATIC;
6865543Scgimport static com.sun.tools.javac.code.Kinds.*;
6965543Scgimport static com.sun.tools.javac.code.Kinds.Kind.*;
7065543Scgimport static com.sun.tools.javac.code.TypeTag.*;
7165543Scgimport static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
7265543Scgimport static com.sun.tools.javac.tree.JCTree.Tag.*;
7365543Scg
7465543Scg/** Helper class for name resolution, used mostly by the attribution phase.
7565543Scg *
7665543Scg *  <p><b>This is NOT part of any supported API.
7765543Scg *  If you write code that depends on this, you do so at your own risk.
78137500Sjulian *  This code and its internal interfaces are subject to change or
79137500Sjulian *  deletion without notice.</b>
80137500Sjulian */
81137500Sjulianpublic class Resolve {
82137500Sjulian    protected static final Context.Key<Resolve> resolveKey = new Context.Key<>();
83137500Sjulian
8465543Scg    Names names;
8565543Scg    Log log;
8665543Scg    Symtab syms;
8784658Scg    Attr attr;
8865543Scg    DeferredAttr deferredAttr;
8965543Scg    Check chk;
90137500Sjulian    Infer infer;
91137500Sjulian    ClassFinder finder;
92137500Sjulian    Types types;
93137500Sjulian    JCDiagnostic.Factory diags;
94137500Sjulian    public final boolean allowMethodHandles;
95137500Sjulian    public final boolean allowFunctionalInterfaceMostSpecific;
96137500Sjulian    public final boolean checkVarargsAccessAfterResolution;
97137500Sjulian    private final boolean debugResolve;
98137500Sjulian    private final boolean compactMethodDiags;
99137500Sjulian    final EnumSet<VerboseResolutionMode> verboseResolutionMode;
100137500Sjulian
10165543Scg    WriteableScope polymorphicSignatureScope;
10265543Scg
10365543Scg    protected Resolve(Context context) {
10465543Scg        context.put(resolveKey, this);
105137500Sjulian        syms = Symtab.instance(context);
10665543Scg
107137500Sjulian        varNotFound = new SymbolNotFoundError(ABSENT_VAR);
108137500Sjulian        methodNotFound = new SymbolNotFoundError(ABSENT_MTH);
10974763Scg        typeNotFound = new SymbolNotFoundError(ABSENT_TYP);
11074763Scg        referenceNotFound = new ReferenceLookupResult(methodNotFound, null);
111137500Sjulian
112137500Sjulian        names = Names.instance(context);
113137500Sjulian        log = Log.instance(context);
114137500Sjulian        attr = Attr.instance(context);
115137500Sjulian        deferredAttr = DeferredAttr.instance(context);
116137500Sjulian        chk = Check.instance(context);
11770291Scg        infer = Infer.instance(context);
118137500Sjulian        finder = ClassFinder.instance(context);
119137500Sjulian        types = Types.instance(context);
120137500Sjulian        diags = JCDiagnostic.Factory.instance(context);
121137500Sjulian        Source source = Source.instance(context);
12265543Scg        Options options = Options.instance(context);
12365543Scg        debugResolve = options.isSet("debugresolve");
124137500Sjulian        compactMethodDiags = options.isSet(Option.XDIAGS, "compact") ||
125137500Sjulian                options.isUnset(Option.XDIAGS) && options.isUnset("rawDiagnostics");
126137500Sjulian        verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
127137500Sjulian        Target target = Target.instance(context);
128137500Sjulian        allowMethodHandles = target.hasMethodHandles();
129137500Sjulian        allowFunctionalInterfaceMostSpecific = source.allowFunctionalInterfaceMostSpecific();
130137500Sjulian        checkVarargsAccessAfterResolution =
131137500Sjulian                source.allowPostApplicabilityVarargsAccessCheck();
132137500Sjulian        polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
133137500Sjulian
134137500Sjulian        inapplicableMethodException = new InapplicableMethodException(diags);
135137500Sjulian    }
136137500Sjulian
137137500Sjulian    /** error symbols, which are returned when resolution fails
138137500Sjulian     */
139137500Sjulian    private final SymbolNotFoundError varNotFound;
140137500Sjulian    private final SymbolNotFoundError methodNotFound;
141137500Sjulian    private final SymbolNotFoundError typeNotFound;
142137500Sjulian
143137500Sjulian    /** empty reference lookup result */
144137500Sjulian    private final ReferenceLookupResult referenceNotFound;
145137500Sjulian
14665543Scg    public static Resolve instance(Context context) {
147137500Sjulian        Resolve instance = context.get(resolveKey);
14865543Scg        if (instance == null)
149137500Sjulian            instance = new Resolve(context);
150137500Sjulian        return instance;
15165543Scg    }
15265543Scg
15365543Scg    private static Symbol bestOf(Symbol s1,
15465543Scg                                 Symbol s2) {
15565543Scg        return s1.kind.betterThan(s2.kind) ? s1 : s2;
15665543Scg    }
15765543Scg
15865543Scg    // <editor-fold defaultstate="collapsed" desc="Verbose resolution diagnostics support">
15965543Scg    enum VerboseResolutionMode {
160137500Sjulian        SUCCESS("success"),
161137500Sjulian        FAILURE("failure"),
16265543Scg        APPLICABLE("applicable"),
163137500Sjulian        INAPPLICABLE("inapplicable"),
164137500Sjulian        DEFERRED_INST("deferred-inference"),
165137500Sjulian        PREDEF("predef"),
16665543Scg        OBJECT_INIT("object-init"),
16765543Scg        INTERNAL("internal");
168137500Sjulian
169137500Sjulian        final String opt;
170137500Sjulian
171137500Sjulian        private VerboseResolutionMode(String opt) {
172137500Sjulian            this.opt = opt;
173137500Sjulian        }
17465543Scg
175137500Sjulian        static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) {
176137500Sjulian            String s = opts.get("verboseResolution");
17765543Scg            EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class);
17865543Scg            if (s == null) return res;
179137500Sjulian            if (s.contains("all")) {
180137500Sjulian                res = EnumSet.allOf(VerboseResolutionMode.class);
181137500Sjulian            }
182137500Sjulian            Collection<String> args = Arrays.asList(s.split(","));
183137500Sjulian            for (VerboseResolutionMode mode : values()) {
184137500Sjulian                if (args.contains(mode.opt)) {
185137500Sjulian                    res.add(mode);
186137500Sjulian                } else if (args.contains("-" + mode.opt)) {
187137500Sjulian                    res.remove(mode);
188137500Sjulian                }
189137500Sjulian            }
190137500Sjulian            return res;
191159732Snetchild        }
192159732Snetchild    }
193159732Snetchild
194248085Smarius    void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site,
195137500Sjulian            List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) {
196137500Sjulian        boolean success = !bestSoFar.kind.isResolutionError();
197137500Sjulian
198137500Sjulian        if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) {
199137500Sjulian            return;
200166279Sariff        } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) {
201166279Sariff            return;
202137500Sjulian        }
203137500Sjulian
204137500Sjulian        if (bestSoFar.name == names.init &&
205137500Sjulian                bestSoFar.owner == syms.objectType.tsym &&
206137500Sjulian                !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) {
207137500Sjulian            return; //skip diags for Object constructor resolution
208166279Sariff        } else if (site == syms.predefClass.type &&
209137500Sjulian                !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) {
210260298Sdim            return; //skip spurious diags for predef symbols (i.e. operators)
211166279Sariff        } else if (currentResolutionContext.internalResolution &&
212166279Sariff                !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) {
213166279Sariff            return;
214260298Sdim        }
215166279Sariff
216166279Sariff        int pos = 0;
217137500Sjulian        int mostSpecificPos = -1;
218166279Sariff        ListBuffer<JCDiagnostic> subDiags = new ListBuffer<>();
219137500Sjulian        for (Candidate c : currentResolutionContext.candidates) {
220166279Sariff            if (currentResolutionContext.step != c.step ||
221166279Sariff                    (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) ||
222166279Sariff                    (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) {
223166279Sariff                continue;
224166279Sariff            } else {
225166279Sariff                subDiags.append(c.isApplicable() ?
226166279Sariff                        getVerboseApplicableCandidateDiag(pos, c.sym, c.mtype) :
22765543Scg                        getVerboseInapplicableCandidateDiag(pos, c.sym, c.details));
228166279Sariff                if (c.sym == bestSoFar)
229166279Sariff                    mostSpecificPos = pos;
230166279Sariff                pos++;
231166279Sariff            }
232166279Sariff        }
233166279Sariff        String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1";
234166279Sariff        List<Type> argtypes2 = argtypes.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, bestSoFar, currentResolutionContext.step));
235166279Sariff        JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name,
23665543Scg                site.tsym, mostSpecificPos, currentResolutionContext.step,
237166279Sariff                methodArguments(argtypes2),
23865543Scg                methodArguments(typeargtypes));
239166279Sariff        JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList());
240166279Sariff        log.report(d);
241166279Sariff    }
24265543Scg
243166279Sariff    JCDiagnostic getVerboseApplicableCandidateDiag(int pos, Symbol sym, Type inst) {
244166279Sariff        JCDiagnostic subDiag = null;
245166279Sariff        if (sym.type.hasTag(FORALL)) {
246166279Sariff            subDiag = diags.fragment("partial.inst.sig", inst);
247166279Sariff        }
248166279Sariff
24965543Scg        String key = subDiag == null ?
250166279Sariff                "applicable.method.found" :
251166279Sariff                "applicable.method.found.1";
252166279Sariff
253166279Sariff        return diags.fragment(key, pos, sym, subDiag);
25465543Scg    }
255166279Sariff
25665543Scg    JCDiagnostic getVerboseInapplicableCandidateDiag(int pos, Symbol sym, JCDiagnostic subDiag) {
257166279Sariff        return diags.fragment("not.applicable.method.found", pos, sym, subDiag);
258166279Sariff    }
259166279Sariff    // </editor-fold>
260166279Sariff
261166279Sariff/* ************************************************************************
262166279Sariff * Identifier resolution
263166279Sariff *************************************************************************/
26465543Scg
265137500Sjulian    /** An environment is "static" if its static level is greater than
266166279Sariff     *  the one of its outer environment
26765543Scg     */
268137500Sjulian    protected static boolean isStatic(Env<AttrContext> env) {
26965543Scg        return env.outer != null && env.info.staticLevel > env.outer.info.staticLevel;
27065543Scg    }
27165543Scg
27265543Scg    /** An environment is an "initializer" if it is a constructor or
273137500Sjulian     *  an instance initializer.
274166279Sariff     */
275166279Sariff    static boolean isInitializer(Env<AttrContext> env) {
27665543Scg        Symbol owner = env.info.scope.owner;
277166279Sariff        return owner.isConstructor() ||
278137500Sjulian            owner.owner.kind == TYP &&
279137500Sjulian            (owner.kind == VAR ||
280137500Sjulian             owner.kind == MTH && (owner.flags() & BLOCK) != 0) &&
281137500Sjulian            (owner.flags() & STATIC) == 0;
282137500Sjulian    }
283137500Sjulian
284137500Sjulian    /** Is class accessible in given evironment?
285137500Sjulian     *  @param env    The current environment.
286137500Sjulian     *  @param c      The class whose accessibility is checked.
287137500Sjulian     */
288137500Sjulian    public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) {
289137500Sjulian        return isAccessible(env, c, false);
290137500Sjulian    }
291260298Sdim
292166279Sariff    public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) {
293137500Sjulian
294137500Sjulian        /* 15.9.5.1: Note that it is possible for the signature of the anonymous constructor
295137500Sjulian           to refer to an inaccessible type
296137500Sjulian        */
297137500Sjulian        if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0)
298137500Sjulian            return true;
299137500Sjulian
300137500Sjulian        boolean isAccessible = false;
301137500Sjulian        switch ((short)(c.flags() & AccessFlags)) {
302137500Sjulian            case PRIVATE:
303137500Sjulian                isAccessible =
304137500Sjulian                    env.enclClass.sym.outermostClass() ==
305137500Sjulian                    c.owner.outermostClass();
306260298Sdim                break;
307137500Sjulian            case 0:
308137500Sjulian                isAccessible =
309137500Sjulian                    env.toplevel.packge == c.owner // fast special case
310137500Sjulian                    ||
311137500Sjulian                    env.toplevel.packge == c.packge();
312137500Sjulian                break;
313260298Sdim            default: // error recovery
314166279Sariff            case PUBLIC:
315137500Sjulian                isAccessible = true;
316137500Sjulian                break;
317137500Sjulian            case PROTECTED:
318137500Sjulian                isAccessible =
319137500Sjulian                    env.toplevel.packge == c.owner // fast special case
320137500Sjulian                    ||
321137500Sjulian                    env.toplevel.packge == c.packge()
322137500Sjulian                    ||
323137500Sjulian                    isInnerSubClass(env.enclClass.sym, c.owner);
324137500Sjulian                break;
325137500Sjulian        }
326137500Sjulian        return (checkInner == false || c.type.getEnclosingType() == Type.noType) ?
327137500Sjulian            isAccessible :
328137500Sjulian            isAccessible && isAccessible(env, c.type.getEnclosingType(), checkInner);
329260298Sdim    }
330137500Sjulian    //where
331137500Sjulian        /** Is given class a subclass of given base class, or an inner class
332137500Sjulian         *  of a subclass?
333137500Sjulian         *  Return null if no such class exists.
334137500Sjulian         *  @param c     The class which is the subclass or is contained in it.
335137500Sjulian         *  @param base  The base class
33670134Scg         */
33770134Scg        private boolean isInnerSubClass(ClassSymbol c, Symbol base) {
338137500Sjulian            while (c != null && !c.isSubClass(base, types)) {
339137500Sjulian                c = c.owner.enclClass();
340166279Sariff            }
341137500Sjulian            return c != null;
34265543Scg        }
343137500Sjulian
34470134Scg    boolean isAccessible(Env<AttrContext> env, Type t) {
345137500Sjulian        return isAccessible(env, t, false);
346137500Sjulian    }
347137500Sjulian
348137500Sjulian    boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) {
349137500Sjulian        return (t.hasTag(ARRAY))
350137500Sjulian            ? isAccessible(env, types.cvarUpperBound(types.elemtype(t)))
35170134Scg            : isAccessible(env, t.tsym, checkInner);
35270134Scg    }
353137500Sjulian
354166279Sariff    /** Is symbol accessible as a member of given type in given environment?
355137500Sjulian     *  @param env    The current environment.
35670134Scg     *  @param site   The type of which the tested symbol is regarded
357137500Sjulian     *                as a member.
35865543Scg     *  @param sym    The symbol.
35965543Scg     */
360137500Sjulian    public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) {
361137500Sjulian        return isAccessible(env, site, sym, false);
362137500Sjulian    }
363137500Sjulian    public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) {
36465543Scg        if (sym.name == names.init && sym.owner != site.tsym) return false;
36565543Scg
366137500Sjulian        /* 15.9.5.1: Note that it is possible for the signature of the anonymous constructor
367137500Sjulian           to refer to an inaccessible type
36865543Scg        */
36965543Scg        if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0)
370137500Sjulian            return true;
371137500Sjulian
372137500Sjulian        switch ((short)(sym.flags() & AccessFlags)) {
373137500Sjulian        case PRIVATE:
374137500Sjulian            return
375137500Sjulian                (env.enclClass.sym == sym.owner // fast special case
37665543Scg                 ||
37765543Scg                 env.enclClass.sym.outermostClass() ==
378137500Sjulian                 sym.owner.outermostClass())
37965543Scg                &&
38065543Scg                sym.isInheritedIn(site.tsym, types);
381166279Sariff        case 0:
382137500Sjulian            return
38365543Scg                (env.toplevel.packge == sym.owner.owner // fast special case
38465543Scg                 ||
385137500Sjulian                 env.toplevel.packge == sym.packge())
38665543Scg                &&
38765543Scg                isAccessible(env, site, checkInner)
38870134Scg                &&
38965543Scg                sym.isInheritedIn(site.tsym, types)
39065543Scg                &&
391137500Sjulian                notOverriddenIn(site, sym);
392137500Sjulian        case PROTECTED:
39370134Scg            return
394137500Sjulian                (env.toplevel.packge == sym.owner.owner // fast special case
395137500Sjulian                 ||
396137500Sjulian                 env.toplevel.packge == sym.packge()
397137500Sjulian                 ||
398137500Sjulian                 isProtectedAccessible(sym, env.enclClass.sym, site)
399137500Sjulian                 ||
400137500Sjulian                 // OK to select instance method or field from 'super' or type name
40170134Scg                 // (but type names should be disallowed elsewhere!)
40265543Scg                 env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP)
40365543Scg                &&
404166279Sariff                isAccessible(env, site, checkInner)
40565543Scg                &&
40665543Scg                notOverriddenIn(site, sym);
40765543Scg        default: // this case includes erroneous combinations as well
40865543Scg            return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym);
409137500Sjulian        }
41065543Scg    }
41165543Scg    //where
412137500Sjulian    /* `sym' is accessible only if not overridden by
41365543Scg     * another symbol which is a member of `site'
41465543Scg     * (because, if it is overridden, `sym' is not strictly
415137500Sjulian     * speaking a member of `site'). A polymorphic signature method
416137500Sjulian     * cannot be overridden (e.g. MH.invokeExact(Object[])).
41765543Scg     */
41865543Scg    private boolean notOverriddenIn(Type site, Symbol sym) {
419166279Sariff        if (sym.kind != MTH || sym.isConstructor() || sym.isStatic())
42065543Scg            return true;
42165543Scg        else {
422137500Sjulian            Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true);
423137500Sjulian            return (s2 == null || s2 == sym || sym.owner == s2.owner ||
42465543Scg                    !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
42565543Scg        }
426166279Sariff    }
42765543Scg    //where
42865543Scg        /** Is given protected symbol accessible if it is selected from given site
429137500Sjulian         *  and the selection takes place in given class?
430137500Sjulian         *  @param sym     The symbol with protected access
43165543Scg         *  @param c       The class where the access takes place
43265543Scg         *  @site          The type of the qualifier
433166279Sariff         */
434137500Sjulian        private
43565543Scg        boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) {
436137500Sjulian            Type newSite = site.hasTag(TYPEVAR) ? site.getUpperBound() : site;
43765543Scg            while (c != null &&
438137500Sjulian                   !(c.isSubClass(sym.owner, types) &&
439137500Sjulian                     (c.flags() & INTERFACE) == 0 &&
440137500Sjulian                     // In JLS 2e 6.6.2.1, the subclass restriction applies
441137500Sjulian                     // only to instance fields and methods -- types are excluded
442137500Sjulian                     // regardless of whether they are declared 'static' or not.
44365543Scg                     ((sym.flags() & STATIC) != 0 || sym.kind == TYP || newSite.tsym.isSubClass(c, types))))
444137500Sjulian                c = c.owner.enclClass();
445137500Sjulian            return c != null;
44665543Scg        }
44765543Scg
448166279Sariff    /**
449137500Sjulian     * Performs a recursive scan of a type looking for accessibility problems
45065543Scg     * from current attribution environment
451137500Sjulian     */
452137500Sjulian    void checkAccessibleType(Env<AttrContext> env, Type t) {
453137500Sjulian        accessibilityChecker.visit(t, env);
454137500Sjulian    }
45565543Scg
45665543Scg    /**
457166279Sariff     * Accessibility type-visitor
458137500Sjulian     */
45965543Scg    Types.SimpleVisitor<Void, Env<AttrContext>> accessibilityChecker =
460137500Sjulian            new Types.SimpleVisitor<Void, Env<AttrContext>>() {
461137500Sjulian
462137500Sjulian        void visit(List<Type> ts, Env<AttrContext> env) {
463137500Sjulian            for (Type t : ts) {
464166279Sariff                visit(t, env);
465166279Sariff            }
466137500Sjulian        }
467137500Sjulian
46865543Scg        public Void visitType(Type t, Env<AttrContext> env) {
46965543Scg            return null;
47065543Scg        }
471137573Sru
472137500Sjulian        @Override
473137500Sjulian        public Void visitArrayType(ArrayType t, Env<AttrContext> env) {
47465543Scg            visit(t.elemtype, env);
475137500Sjulian            return null;
476137500Sjulian        }
477137500Sjulian
478137500Sjulian        @Override
479137500Sjulian        public Void visitClassType(ClassType t, Env<AttrContext> env) {
480137500Sjulian            visit(t.getTypeArguments(), env);
481137500Sjulian            if (!isAccessible(env, t, true)) {
482137500Sjulian                accessBase(new AccessError(t.tsym), env.tree.pos(), env.enclClass.sym, t, t.tsym.name, true);
483137500Sjulian            }
484137500Sjulian            return null;
485137500Sjulian        }
486137500Sjulian
487137500Sjulian        @Override
48865543Scg        public Void visitWildcardType(WildcardType t, Env<AttrContext> env) {
489166279Sariff            visit(t.type, env);
490137500Sjulian            return null;
491137500Sjulian        }
492137500Sjulian
49365543Scg        @Override
494137500Sjulian        public Void visitMethodType(MethodType t, Env<AttrContext> env) {
495137500Sjulian            visit(t.getParameterTypes(), env);
496137500Sjulian            visit(t.getReturnType(), env);
49765543Scg            visit(t.getThrownTypes(), env);
498137500Sjulian            return null;
499137500Sjulian        }
50065543Scg    };
50165543Scg
50265543Scg    /** Try to instantiate the type of a method so that it fits
50365543Scg     *  given type arguments and argument types. If successful, return
50465543Scg     *  the method's instantiated type, else return null.
505137500Sjulian     *  The instantiation will take into account an additional leading
50665543Scg     *  formal parameter if the method is an instance method seen as a member
50765543Scg     *  of an under determined site. In this case, we treat site as an additional
50865543Scg     *  parameter and the parameters of the class containing the method as
50965543Scg     *  additional type variables that get instantiated.
510166279Sariff     *
51165543Scg     *  @param env         The current environment
51265543Scg     *  @param site        The type of which the method is a member.
513137500Sjulian     *  @param m           The method symbol.
514137500Sjulian     *  @param argtypes    The invocation's given value arguments.
515137500Sjulian     *  @param typeargtypes    The invocation's given type arguments.
51665543Scg     *  @param allowBoxing Allow boxing conversions of arguments.
51765543Scg     *  @param useVarargs Box trailing arguments into an array for varargs.
51865543Scg     */
519166279Sariff    Type rawInstantiate(Env<AttrContext> env,
52065543Scg                        Type site,
52165543Scg                        Symbol m,
522137500Sjulian                        ResultInfo resultInfo,
523137500Sjulian                        List<Type> argtypes,
524137500Sjulian                        List<Type> typeargtypes,
52565543Scg                        boolean allowBoxing,
52665543Scg                        boolean useVarargs,
52765543Scg                        Warner warn) throws Infer.InferenceException {
528137500Sjulian        Type mt = types.memberType(site, m);
529137500Sjulian        // tvars is the list of formal type variables for which type arguments
53065543Scg        // need to inferred.
53165543Scg        List<Type> tvars = List.nil();
532166279Sariff        if (typeargtypes == null) typeargtypes = List.nil();
533166279Sariff        if (!mt.hasTag(FORALL) && typeargtypes.nonEmpty()) {
53465543Scg            // This is not a polymorphic method, but typeargs are supplied
53565543Scg            // which is fine, see JLS 15.12.2.1
536137500Sjulian        } else if (mt.hasTag(FORALL) && typeargtypes.nonEmpty()) {
537137500Sjulian            ForAll pmt = (ForAll) mt;
53865543Scg            if (typeargtypes.length() != pmt.tvars.length())
539166279Sariff                throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
54065543Scg            // Check type arguments are within bounds
541166279Sariff            List<Type> formals = pmt.tvars;
54265543Scg            List<Type> actuals = typeargtypes;
54365543Scg            while (formals.nonEmpty() && actuals.nonEmpty()) {
544137500Sjulian                List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head),
545137500Sjulian                                                pmt.tvars, typeargtypes);
54665543Scg                for (; bounds.nonEmpty(); bounds = bounds.tail) {
54765543Scg                    if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn))
548166279Sariff                        throw inapplicableMethodException.setMessage("explicit.param.do.not.conform.to.bounds",actuals.head, bounds);
549166279Sariff                }
55065543Scg                formals = formals.tail;
55165543Scg                actuals = actuals.tail;
55265543Scg            }
55365543Scg            mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes);
554166279Sariff        } else if (mt.hasTag(FORALL)) {
55565543Scg            ForAll pmt = (ForAll) mt;
556166279Sariff            List<Type> tvars1 = types.newInstances(pmt.tvars);
55765543Scg            tvars = tvars.appendList(tvars1);
55865543Scg            mt = types.subst(pmt.qtype, pmt.tvars, tvars1);
55965543Scg        }
56065543Scg
56165543Scg        // find out whether we need to go the slow route via infer
562137500Sjulian        boolean instNeeded = tvars.tail != null; /*inlined: tvars.nonEmpty()*/
563137500Sjulian        for (List<Type> l = argtypes;
56465543Scg             l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
565166279Sariff             l = l.tail) {
566137500Sjulian            if (l.head.hasTag(FORALL)) instNeeded = true;
56765543Scg        }
568137500Sjulian
56965543Scg        if (instNeeded) {
570137500Sjulian            return infer.instantiateMethod(env,
571137500Sjulian                                    tvars,
572137500Sjulian                                    (MethodType)mt,
573137500Sjulian                                    resultInfo,
574137500Sjulian                                    (MethodSymbol)m,
575137500Sjulian                                    argtypes,
576137500Sjulian                                    allowBoxing,
577137500Sjulian                                    useVarargs,
578137500Sjulian                                    currentResolutionContext,
579137500Sjulian                                    warn);
580137500Sjulian        }
581137500Sjulian
58265543Scg        DeferredAttr.DeferredAttrContext dc = currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn);
58365543Scg        currentResolutionContext.methodCheck.argumentsAcceptable(env, dc,
58465543Scg                                argtypes, mt.getParameterTypes(), warn);
58565543Scg        dc.complete();
58665543Scg        return mt;
58765543Scg    }
58865543Scg
589166279Sariff    Type checkMethod(Env<AttrContext> env,
59065543Scg                     Type site,
59165543Scg                     Symbol m,
59265543Scg                     ResultInfo resultInfo,
59365543Scg                     List<Type> argtypes,
594137500Sjulian                     List<Type> typeargtypes,
595137500Sjulian                     Warner warn) {
59665543Scg        MethodResolutionContext prevContext = currentResolutionContext;
59765543Scg        try {
59865543Scg            currentResolutionContext = new MethodResolutionContext();
599137500Sjulian            currentResolutionContext.attrMode = (resultInfo.pt == Infer.anyPoly) ?
60065543Scg                    AttrMode.SPECULATIVE : DeferredAttr.AttrMode.CHECK;
601137500Sjulian            if (env.tree.hasTag(JCTree.Tag.REFERENCE)) {
602137500Sjulian                //method/constructor references need special check class
60365543Scg                //to handle inference variables in 'argtypes' (might happen
604137500Sjulian                //during an unsticking round)
605137500Sjulian                currentResolutionContext.methodCheck =
60665543Scg                        new MethodReferenceCheck(resultInfo.checkContext.inferenceContext());
60765543Scg            }
60865543Scg            MethodResolutionPhase step = currentResolutionContext.step = env.info.pendingResolutionPhase;
60965543Scg            return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
610137500Sjulian                    step.isBoxingRequired(), step.isVarargsRequired(), warn);
61165543Scg        }
61265543Scg        finally {
613137500Sjulian            currentResolutionContext = prevContext;
614137500Sjulian        }
615137500Sjulian    }
616137500Sjulian
61765543Scg    /** Same but returns null instead throwing a NoInstanceException
618137500Sjulian     */
61965543Scg    Type instantiate(Env<AttrContext> env,
620137500Sjulian                     Type site,
621137500Sjulian                     Symbol m,
622137500Sjulian                     ResultInfo resultInfo,
62365543Scg                     List<Type> argtypes,
624137500Sjulian                     List<Type> typeargtypes,
625137500Sjulian                     boolean allowBoxing,
62665543Scg                     boolean useVarargs,
62765543Scg                     Warner warn) {
62865543Scg        try {
62965543Scg            return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
63065543Scg                                  allowBoxing, useVarargs, warn);
63165543Scg        } catch (InapplicableMethodException ex) {
63265543Scg            return null;
63365543Scg        }
63465543Scg    }
63565543Scg
63665543Scg    /**
63765543Scg     * This interface defines an entry point that should be used to perform a
63865543Scg     * method check. A method check usually consist in determining as to whether
63965543Scg     * a set of types (actuals) is compatible with another set of types (formals).
64065543Scg     * Since the notion of compatibility can vary depending on the circumstances,
64165543Scg     * this interfaces allows to easily add new pluggable method check routines.
64265543Scg     */
64365543Scg    interface MethodCheck {
64465543Scg        /**
64565543Scg         * Main method check routine. A method check usually consist in determining
646137500Sjulian         * as to whether a set of types (actuals) is compatible with another set of
64765543Scg         * types (formals). If an incompatibility is found, an unchecked exception
64865543Scg         * is assumed to be thrown.
64965543Scg         */
65065543Scg        void argumentsAcceptable(Env<AttrContext> env,
651137500Sjulian                                DeferredAttrContext deferredAttrContext,
652137500Sjulian                                List<Type> argtypes,
653137500Sjulian                                List<Type> formals,
654137500Sjulian                                Warner warn);
655137500Sjulian
656137500Sjulian        /**
657137500Sjulian         * Retrieve the method check object that will be used during a
658137500Sjulian         * most specific check.
659137500Sjulian         */
660137500Sjulian        MethodCheck mostSpecificCheck(List<Type> actuals);
661137500Sjulian    }
662137500Sjulian
663137500Sjulian    /**
664137500Sjulian     * Helper enum defining all method check diagnostics (used by resolveMethodCheck).
665137500Sjulian     */
666137500Sjulian    enum MethodCheckDiag {
667137500Sjulian        /**
668137500Sjulian         * Actuals and formals differs in length.
669137500Sjulian         */
670137500Sjulian        ARITY_MISMATCH("arg.length.mismatch", "infer.arg.length.mismatch"),
671137500Sjulian        /**
672137500Sjulian         * An actual is incompatible with a formal.
673137500Sjulian         */
674137500Sjulian        ARG_MISMATCH("no.conforming.assignment.exists", "infer.no.conforming.assignment.exists"),
675137500Sjulian        /**
676137500Sjulian         * An actual is incompatible with the varargs element type.
677137500Sjulian         */
678137500Sjulian        VARARG_MISMATCH("varargs.argument.mismatch", "infer.varargs.argument.mismatch"),
679137500Sjulian        /**
68065543Scg         * The varargs element type is inaccessible.
681137500Sjulian         */
682137500Sjulian        INACCESSIBLE_VARARGS("inaccessible.varargs.type", "inaccessible.varargs.type");
683137500Sjulian
684137500Sjulian        final String basicKey;
685137500Sjulian        final String inferKey;
686137500Sjulian
687137500Sjulian        MethodCheckDiag(String basicKey, String inferKey) {
688137500Sjulian            this.basicKey = basicKey;
68965543Scg            this.inferKey = inferKey;
690137500Sjulian        }
691137500Sjulian
692137500Sjulian        String regex() {
69365543Scg            return String.format("([a-z]*\\.)*(%s|%s)", basicKey, inferKey);
69465543Scg        }
69565543Scg    }
69665543Scg
69765543Scg    /**
69865543Scg     * Dummy method check object. All methods are deemed applicable, regardless
699137500Sjulian     * of their formal parameter types.
70065543Scg     */
701137500Sjulian    MethodCheck nilMethodCheck = new MethodCheck() {
702137500Sjulian        public void argumentsAcceptable(Env<AttrContext> env, DeferredAttrContext deferredAttrContext, List<Type> argtypes, List<Type> formals, Warner warn) {
703137500Sjulian            //do nothing - method always applicable regardless of actuals
70465543Scg        }
705137500Sjulian
70665543Scg        public MethodCheck mostSpecificCheck(List<Type> actuals) {
70765543Scg            return this;
70865543Scg        }
709137500Sjulian    };
710137500Sjulian
71165543Scg    /**
712137500Sjulian     * Base class for 'real' method checks. The class defines the logic for
713137500Sjulian     * iterating through formals and actuals and provides and entry point
714137500Sjulian     * that can be used by subclasses in order to define the actual check logic.
715137500Sjulian     */
716137500Sjulian    abstract class AbstractMethodCheck implements MethodCheck {
717137500Sjulian        @Override
71865543Scg        public void argumentsAcceptable(final Env<AttrContext> env,
71965543Scg                                    DeferredAttrContext deferredAttrContext,
72065543Scg                                    List<Type> argtypes,
72165543Scg                                    List<Type> formals,
72265543Scg                                    Warner warn) {
723137500Sjulian            //should we expand formals?
724137500Sjulian            boolean useVarargs = deferredAttrContext.phase.isVarargsRequired();
725137500Sjulian            JCTree callTree = treeForDiagnostics(env);
726137500Sjulian            List<JCExpression> trees = TreeInfo.args(callTree);
727137500Sjulian
728137500Sjulian            //inference context used during this method check
72965543Scg            InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
730137500Sjulian
731137500Sjulian            Type varargsFormal = useVarargs ? formals.last() : null;
732137500Sjulian
73365543Scg            if (varargsFormal == null &&
73465543Scg                    argtypes.size() != formals.size()) {
73565543Scg                reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
73665543Scg            }
73765543Scg
73865543Scg            while (argtypes.nonEmpty() && formals.head != varargsFormal) {
73965543Scg                DiagnosticPosition pos = trees != null ? trees.head : null;
74065543Scg                checkArg(pos, false, argtypes.head, formals.head, deferredAttrContext, warn);
74165543Scg                argtypes = argtypes.tail;
74265543Scg                formals = formals.tail;
74365543Scg                trees = trees != null ? trees.tail : trees;
744137500Sjulian            }
745137500Sjulian
746137500Sjulian            if (formals.head != varargsFormal) {
747137500Sjulian                reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
74865543Scg            }
74965543Scg
75065543Scg            if (useVarargs) {
75165543Scg                //note: if applicability check is triggered by most specific test,
752137500Sjulian                //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
753137500Sjulian                final Type elt = types.elemtype(varargsFormal);
754137500Sjulian                while (argtypes.nonEmpty()) {
755137500Sjulian                    DiagnosticPosition pos = trees != null ? trees.head : null;
756137500Sjulian                    checkArg(pos, true, argtypes.head, elt, deferredAttrContext, warn);
757137500Sjulian                    argtypes = argtypes.tail;
758137500Sjulian                    trees = trees != null ? trees.tail : trees;
759137500Sjulian                }
760137500Sjulian            }
761137500Sjulian        }
762137500Sjulian
763137500Sjulian            // where
764137500Sjulian            private JCTree treeForDiagnostics(Env<AttrContext> env) {
765137500Sjulian                return env.info.preferredTreeForDiagnostics != null ? env.info.preferredTreeForDiagnostics : env.tree;
766137500Sjulian            }
767137500Sjulian
768137500Sjulian        /**
769137500Sjulian         * Does the actual argument conforms to the corresponding formal?
770137500Sjulian         */
771137500Sjulian        abstract void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn);
772137500Sjulian
773166279Sariff        protected void reportMC(DiagnosticPosition pos, MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) {
774166279Sariff            boolean inferDiag = inferenceContext != infer.emptyContext;
775137500Sjulian            InapplicableMethodException ex = inferDiag ?
776137500Sjulian                    infer.inferenceException : inapplicableMethodException;
777137500Sjulian            if (inferDiag && (!diag.inferKey.equals(diag.basicKey))) {
778137500Sjulian                Object[] args2 = new Object[args.length + 1];
779137500Sjulian                System.arraycopy(args, 0, args2, 1, args.length);
780137500Sjulian                args2[0] = inferenceContext.inferenceVars();
781137500Sjulian                args = args2;
782137500Sjulian            }
783137500Sjulian            String key = inferDiag ? diag.inferKey : diag.basicKey;
784137500Sjulian            throw ex.setMessage(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args));
785137500Sjulian        }
786137500Sjulian
787137500Sjulian        public MethodCheck mostSpecificCheck(List<Type> actuals) {
788137500Sjulian            return nilMethodCheck;
789137500Sjulian        }
790137500Sjulian
791137500Sjulian    }
792137500Sjulian
793137500Sjulian    /**
794137500Sjulian     * Arity-based method check. A method is applicable if the number of actuals
795137500Sjulian     * supplied conforms to the method signature.
796137500Sjulian     */
797137500Sjulian    MethodCheck arityMethodCheck = new AbstractMethodCheck() {
798137500Sjulian        @Override
799137500Sjulian        void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
800137500Sjulian            //do nothing - actual always compatible to formals
801137500Sjulian        }
802137500Sjulian
803137500Sjulian        @Override
804137500Sjulian        public String toString() {
805137500Sjulian            return "arityMethodCheck";
806137500Sjulian        }
807137500Sjulian    };
808137500Sjulian
809137500Sjulian    List<Type> dummyArgs(int length) {
810137500Sjulian        ListBuffer<Type> buf = new ListBuffer<>();
811137500Sjulian        for (int i = 0 ; i < length ; i++) {
812137500Sjulian            buf.append(Type.noType);
813137500Sjulian        }
814137500Sjulian        return buf.toList();
815137500Sjulian    }
816137500Sjulian
817137500Sjulian    /**
818137500Sjulian     * Main method applicability routine. Given a list of actual types A,
819137500Sjulian     * a list of formal types F, determines whether the types in A are
820137500Sjulian     * compatible (by method invocation conversion) with the types in F.
821137500Sjulian     *
822137500Sjulian     * Since this routine is shared between overload resolution and method
823137500Sjulian     * type-inference, a (possibly empty) inference context is used to convert
824137500Sjulian     * formal types to the corresponding 'undet' form ahead of a compatibility
825137500Sjulian     * check so that constraints can be propagated and collected.
826137500Sjulian     *
827137500Sjulian     * Moreover, if one or more types in A is a deferred type, this routine uses
828137500Sjulian     * DeferredAttr in order to perform deferred attribution. If one or more actual
829137500Sjulian     * deferred types are stuck, they are placed in a queue and revisited later
830137500Sjulian     * after the remainder of the arguments have been seen. If this is not sufficient
831137500Sjulian     * to 'unstuck' the argument, a cyclic inference error is called out.
832137500Sjulian     *
833137500Sjulian     * A method check handler (see above) is used in order to report errors.
834137500Sjulian     */
835137500Sjulian    MethodCheck resolveMethodCheck = new AbstractMethodCheck() {
836137500Sjulian
837137500Sjulian        @Override
838137500Sjulian        void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
839137500Sjulian            ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn);
840137500Sjulian            mresult.check(pos, actual);
84165543Scg        }
84265543Scg
84365543Scg        @Override
84465543Scg        public void argumentsAcceptable(final Env<AttrContext> env,
84565543Scg                                    DeferredAttrContext deferredAttrContext,
846137500Sjulian                                    List<Type> argtypes,
847137500Sjulian                                    List<Type> formals,
848137500Sjulian                                    Warner warn) {
849137500Sjulian            super.argumentsAcceptable(env, deferredAttrContext, argtypes, formals, warn);
850137500Sjulian            // should we check varargs element type accessibility?
85165543Scg            if (deferredAttrContext.phase.isVarargsRequired()) {
852137500Sjulian                if (deferredAttrContext.mode == AttrMode.CHECK || !checkVarargsAccessAfterResolution) {
853137500Sjulian                    varargsAccessible(env, types.elemtype(formals.last()), deferredAttrContext.inferenceContext);
854137500Sjulian                }
855137500Sjulian            }
856137500Sjulian        }
857137500Sjulian
858137500Sjulian        /**
859137500Sjulian         * Test that the runtime array element type corresponding to 't' is accessible.  't' should be the
860137500Sjulian         * varargs element type of either the method invocation type signature (after inference completes)
861137500Sjulian         * or the method declaration signature (before inference completes).
862137500Sjulian         */
863137500Sjulian        private void varargsAccessible(final Env<AttrContext> env, final Type t, final InferenceContext inferenceContext) {
864137500Sjulian            if (inferenceContext.free(t)) {
865137500Sjulian                inferenceContext.addFreeTypeListener(List.of(t), new FreeTypeListener() {
866137500Sjulian                    @Override
867137500Sjulian                    public void typesInferred(InferenceContext inferenceContext) {
868137500Sjulian                        varargsAccessible(env, inferenceContext.asInstType(t), inferenceContext);
869137500Sjulian                    }
870137500Sjulian                });
871137500Sjulian            } else {
872137500Sjulian                if (!isAccessible(env, types.erasure(t))) {
873137500Sjulian                    Symbol location = env.enclClass.sym;
874137500Sjulian                    reportMC(env.tree, MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location);
875137500Sjulian                }
876137500Sjulian            }
87765543Scg        }
878137500Sjulian
879137500Sjulian        private ResultInfo methodCheckResult(final boolean varargsCheck, Type to,
88065543Scg                final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) {
881137500Sjulian            CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) {
882137500Sjulian                MethodCheckDiag methodDiag = varargsCheck ?
883137500Sjulian                                 MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH;
88465543Scg
88565543Scg                @Override
88665543Scg                public void report(DiagnosticPosition pos, JCDiagnostic details) {
887137500Sjulian                    reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details);
888137500Sjulian                }
88965543Scg            };
890137500Sjulian            return new MethodResultInfo(to, checkContext);
891137500Sjulian        }
892137500Sjulian
893137500Sjulian        @Override
894137500Sjulian        public MethodCheck mostSpecificCheck(List<Type> actuals) {
895137500Sjulian            return new MostSpecificCheck(actuals);
896137500Sjulian        }
897137500Sjulian
898137500Sjulian        @Override
899137500Sjulian        public String toString() {
900137500Sjulian            return "resolveMethodCheck";
901137500Sjulian        }
90265543Scg    };
903137500Sjulian
904137500Sjulian    /**
905137500Sjulian     * This class handles method reference applicability checks; since during
906137500Sjulian     * these checks it's sometime possible to have inference variables on
907137500Sjulian     * the actual argument types list, the method applicability check must be
90865543Scg     * extended so that inference variables are 'opened' as needed.
909137500Sjulian     */
910137500Sjulian    class MethodReferenceCheck extends AbstractMethodCheck {
911137500Sjulian
91265543Scg        InferenceContext pendingInferenceContext;
913137500Sjulian
914137500Sjulian        MethodReferenceCheck(InferenceContext pendingInferenceContext) {
915137500Sjulian            this.pendingInferenceContext = pendingInferenceContext;
916137500Sjulian        }
917137500Sjulian
918137500Sjulian        @Override
919137500Sjulian        void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
920137500Sjulian            ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn);
921137500Sjulian            mresult.check(pos, actual);
922137500Sjulian        }
923137500Sjulian
924137500Sjulian        private ResultInfo methodCheckResult(final boolean varargsCheck, Type to,
925137500Sjulian                final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) {
92665543Scg            CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) {
92765543Scg                MethodCheckDiag methodDiag = varargsCheck ?
92865543Scg                                 MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH;
92965543Scg
93065543Scg                @Override
931137500Sjulian                public boolean compatible(Type found, Type req, Warner warn) {
932137500Sjulian                    found = pendingInferenceContext.asUndetVar(found);
933137500Sjulian                    if (found.hasTag(UNDETVAR) && req.isPrimitive()) {
934137500Sjulian                        req = types.boxedClass(req).type;
935137500Sjulian                    }
936137500Sjulian                    return super.compatible(found, req, warn);
93765543Scg                }
938137500Sjulian
93965543Scg                @Override
940137500Sjulian                public void report(DiagnosticPosition pos, JCDiagnostic details) {
941137500Sjulian                    reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details);
942137500Sjulian                }
943137500Sjulian            };
944137500Sjulian            return new MethodResultInfo(to, checkContext);
945137500Sjulian        }
946137500Sjulian
947137500Sjulian        @Override
948137500Sjulian        public MethodCheck mostSpecificCheck(List<Type> actuals) {
94965543Scg            return new MostSpecificCheck(actuals);
95065543Scg        }
951137500Sjulian
952137500Sjulian        @Override
953137500Sjulian        public String toString() {
954137500Sjulian            return "MethodReferenceCheck";
955137500Sjulian        }
956137500Sjulian    }
957137500Sjulian
958137500Sjulian    /**
959137500Sjulian     * Check context to be used during method applicability checks. A method check
960137500Sjulian     * context might contain inference variables.
961137500Sjulian     */
962137500Sjulian    abstract class MethodCheckContext implements CheckContext {
963137500Sjulian
964137500Sjulian        boolean strict;
965137500Sjulian        DeferredAttrContext deferredAttrContext;
966137500Sjulian        Warner rsWarner;
967137500Sjulian
968137500Sjulian        public MethodCheckContext(boolean strict, DeferredAttrContext deferredAttrContext, Warner rsWarner) {
969137500Sjulian           this.strict = strict;
970137500Sjulian           this.deferredAttrContext = deferredAttrContext;
971137500Sjulian           this.rsWarner = rsWarner;
972137500Sjulian        }
973137500Sjulian
974137500Sjulian        public boolean compatible(Type found, Type req, Warner warn) {
975137500Sjulian            InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
976137500Sjulian            return strict ?
977137500Sjulian                    types.isSubtypeUnchecked(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn) :
978137500Sjulian                    types.isConvertible(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn);
979137500Sjulian        }
980137500Sjulian
981137500Sjulian        public void report(DiagnosticPosition pos, JCDiagnostic details) {
982137500Sjulian            throw inapplicableMethodException.setMessage(details);
983137500Sjulian        }
984137500Sjulian
985137500Sjulian        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
986137500Sjulian            return rsWarner;
987137500Sjulian        }
988137500Sjulian
989137500Sjulian        public InferenceContext inferenceContext() {
990137500Sjulian            return deferredAttrContext.inferenceContext;
991137500Sjulian        }
992137500Sjulian
993137500Sjulian        public DeferredAttrContext deferredAttrContext() {
994137500Sjulian            return deferredAttrContext;
995137500Sjulian        }
996137500Sjulian
997137500Sjulian        @Override
998137500Sjulian        public String toString() {
999137500Sjulian            return "MethodCheckContext";
1000137500Sjulian        }
1001137500Sjulian    }
1002137500Sjulian
1003137500Sjulian    /**
1004137500Sjulian     * ResultInfo class to be used during method applicability checks. Check
1005137500Sjulian     * for deferred types goes through special path.
1006137500Sjulian     */
1007137500Sjulian    class MethodResultInfo extends ResultInfo {
1008137500Sjulian
1009137500Sjulian        public MethodResultInfo(Type pt, CheckContext checkContext) {
1010137500Sjulian            attr.super(KindSelector.VAL, pt, checkContext);
1011137500Sjulian        }
1012137500Sjulian
1013137500Sjulian        @Override
1014137500Sjulian        protected Type check(DiagnosticPosition pos, Type found) {
1015137500Sjulian            if (found.hasTag(DEFERRED)) {
1016137500Sjulian                DeferredType dt = (DeferredType)found;
1017137500Sjulian                return dt.check(this);
1018137500Sjulian            } else {
1019137500Sjulian                Type uResult = U(found);
1020137500Sjulian                Type capturedType = pos == null || pos.getTree() == null ?
1021137500Sjulian                        types.capture(uResult) :
1022137500Sjulian                        checkContext.inferenceContext()
1023137500Sjulian                            .cachedCapture(pos.getTree(), uResult, true);
1024137500Sjulian                return super.check(pos, chk.checkNonVoid(pos, capturedType));
1025137500Sjulian            }
1026137500Sjulian        }
1027137500Sjulian
1028137500Sjulian        /**
1029137500Sjulian         * javac has a long-standing 'simplification' (see 6391995):
1030137500Sjulian         * given an actual argument type, the method check is performed
1031137500Sjulian         * on its upper bound. This leads to inconsistencies when an
1032137500Sjulian         * argument type is checked against itself. For example, given
1033137500Sjulian         * a type-variable T, it is not true that {@code U(T) <: T},
1034137500Sjulian         * so we need to guard against that.
1035137500Sjulian         */
1036137500Sjulian        private Type U(Type found) {
1037137500Sjulian            return found == pt ?
1038137500Sjulian                    found : types.cvarUpperBound(found);
1039137500Sjulian        }
1040137500Sjulian
1041137500Sjulian        @Override
1042137500Sjulian        protected MethodResultInfo dup(Type newPt) {
1043137500Sjulian            return new MethodResultInfo(newPt, checkContext);
1044137500Sjulian        }
1045137500Sjulian
1046137500Sjulian        @Override
1047137500Sjulian        protected ResultInfo dup(CheckContext newContext) {
1048137500Sjulian            return new MethodResultInfo(pt, newContext);
1049137500Sjulian        }
1050137500Sjulian
1051137500Sjulian        @Override
1052137500Sjulian        protected ResultInfo dup(Type newPt, CheckContext newContext) {
1053137500Sjulian            return new MethodResultInfo(newPt, newContext);
1054137500Sjulian        }
1055137500Sjulian    }
1056137500Sjulian
1057137500Sjulian    /**
1058137500Sjulian     * Most specific method applicability routine. Given a list of actual types A,
1059137500Sjulian     * a list of formal types F1, and a list of formal types F2, the routine determines
1060137500Sjulian     * as to whether the types in F1 can be considered more specific than those in F2 w.r.t.
1061137500Sjulian     * argument types A.
106265543Scg     */
1063137500Sjulian    class MostSpecificCheck implements MethodCheck {
1064137500Sjulian
1065137500Sjulian        List<Type> actuals;
1066137500Sjulian
1067137500Sjulian        MostSpecificCheck(List<Type> actuals) {
1068137500Sjulian            this.actuals = actuals;
1069166279Sariff        }
1070137500Sjulian
1071137500Sjulian        @Override
1072137500Sjulian        public void argumentsAcceptable(final Env<AttrContext> env,
1073137500Sjulian                                    DeferredAttrContext deferredAttrContext,
1074137500Sjulian                                    List<Type> formals1,
1075137500Sjulian                                    List<Type> formals2,
1076137500Sjulian                                    Warner warn) {
1077137500Sjulian            formals2 = adjustArgs(formals2, deferredAttrContext.msym, formals1.length(), deferredAttrContext.phase.isVarargsRequired());
1078137500Sjulian            while (formals2.nonEmpty()) {
1079137500Sjulian                ResultInfo mresult = methodCheckResult(formals2.head, deferredAttrContext, warn, actuals.head);
1080137500Sjulian                mresult.check(null, formals1.head);
1081137500Sjulian                formals1 = formals1.tail;
1082137500Sjulian                formals2 = formals2.tail;
1083137500Sjulian                actuals = actuals.isEmpty() ? actuals : actuals.tail;
1084137500Sjulian            }
1085137500Sjulian        }
1086137500Sjulian
1087137500Sjulian       /**
1088137500Sjulian        * Create a method check context to be used during the most specific applicability check
1089137500Sjulian        */
1090137500Sjulian        ResultInfo methodCheckResult(Type to, DeferredAttr.DeferredAttrContext deferredAttrContext,
1091137500Sjulian               Warner rsWarner, Type actual) {
1092137500Sjulian            return attr.new ResultInfo(KindSelector.VAL, to,
1093137500Sjulian                   new MostSpecificCheckContext(deferredAttrContext, rsWarner, actual));
1094137500Sjulian        }
1095137500Sjulian
1096137500Sjulian        /**
1097137500Sjulian         * Subclass of method check context class that implements most specific
1098137500Sjulian         * method conversion. If the actual type under analysis is a deferred type
1099137500Sjulian         * a full blown structural analysis is carried out.
1100137500Sjulian         */
1101137500Sjulian        class MostSpecificCheckContext extends MethodCheckContext {
1102137500Sjulian
1103137500Sjulian            Type actual;
1104137500Sjulian
1105137500Sjulian            public MostSpecificCheckContext(DeferredAttrContext deferredAttrContext, Warner rsWarner, Type actual) {
1106137500Sjulian                super(true, deferredAttrContext, rsWarner);
1107137500Sjulian                this.actual = actual;
1108137500Sjulian            }
1109137500Sjulian
1110137500Sjulian            public boolean compatible(Type found, Type req, Warner warn) {
1111166279Sariff                if (allowFunctionalInterfaceMostSpecific &&
1112137500Sjulian                        unrelatedFunctionalInterfaces(found, req) &&
1113137500Sjulian                        (actual != null && actual.getTag() == DEFERRED)) {
1114137500Sjulian                    DeferredType dt = (DeferredType) actual;
1115137500Sjulian                    JCTree speculativeTree = dt.speculativeTree(deferredAttrContext);
1116137500Sjulian                    if (speculativeTree != deferredAttr.stuckTree) {
1117137500Sjulian                        return functionalInterfaceMostSpecific(found, req, speculativeTree);
1118137500Sjulian                    }
1119137500Sjulian                }
1120137500Sjulian                return compatibleBySubtyping(found, req);
1121137500Sjulian            }
1122137500Sjulian
1123137500Sjulian            private boolean compatibleBySubtyping(Type found, Type req) {
1124137500Sjulian                if (!strict && found.isPrimitive() != req.isPrimitive()) {
1125137500Sjulian                    found = found.isPrimitive() ? types.boxedClass(found).type : types.unboxedType(found);
1126137500Sjulian                }
1127137500Sjulian                return types.isSubtypeNoCapture(found, deferredAttrContext.inferenceContext.asUndetVar(req));
1128137500Sjulian            }
1129137500Sjulian
1130137500Sjulian            /** Whether {@code t} and {@code s} are unrelated functional interface types. */
1131137500Sjulian            private boolean unrelatedFunctionalInterfaces(Type t, Type s) {
1132137500Sjulian                return types.isFunctionalInterface(t.tsym) &&
1133137500Sjulian                       types.isFunctionalInterface(s.tsym) &&
1134137500Sjulian                       types.asSuper(t, s.tsym) == null &&
1135137500Sjulian                       types.asSuper(s, t.tsym) == null;
1136137500Sjulian            }
1137137500Sjulian
1138137500Sjulian            /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
1139166279Sariff            private boolean functionalInterfaceMostSpecific(Type t, Type s, JCTree tree) {
1140137500Sjulian                Type tDesc = types.findDescriptorType(t);
114165543Scg                Type sDesc = types.findDescriptorType(s);
114265543Scg
114365543Scg                // compare type parameters -- can't use Types.hasSameBounds because bounds may have ivars
114465543Scg                final List<Type> tTypeParams = tDesc.getTypeArguments();
1145166279Sariff                final List<Type> sTypeParams = sDesc.getTypeArguments();
114665543Scg                List<Type> tIter = tTypeParams;
114765543Scg                List<Type> sIter = sTypeParams;
1148137500Sjulian                while (tIter.nonEmpty() && sIter.nonEmpty()) {
1149137500Sjulian                    Type tBound = tIter.head.getUpperBound();
115065543Scg                    Type sBound = types.subst(sIter.head.getUpperBound(), sTypeParams, tTypeParams);
1151137500Sjulian                    if (tBound.containsAny(tTypeParams) && inferenceContext().free(sBound)) {
1152137500Sjulian                        return false;
1153137500Sjulian                    }
1154137500Sjulian                    if (!types.isSameType(tBound, inferenceContext().asUndetVar(sBound))) {
1155137500Sjulian                        return false;
1156137500Sjulian                    }
1157137500Sjulian                    tIter = tIter.tail;
1158137500Sjulian                    sIter = sIter.tail;
115965543Scg                }
116065543Scg                if (!tIter.isEmpty() || !sIter.isEmpty()) {
116165543Scg                    return false;
1162166279Sariff                }
1163137500Sjulian
1164137500Sjulian                // compare parameters
1165137500Sjulian                List<Type> tParams = tDesc.getParameterTypes();
1166137500Sjulian                List<Type> sParams = sDesc.getParameterTypes();
1167137500Sjulian                while (tParams.nonEmpty() && sParams.nonEmpty()) {
1168137500Sjulian                    Type tParam = tParams.head;
1169137500Sjulian                    Type sParam = types.subst(sParams.head, sTypeParams, tTypeParams);
1170137500Sjulian                    if (tParam.containsAny(tTypeParams) && inferenceContext().free(sParam)) {
1171137500Sjulian                        return false;
1172137500Sjulian                    }
1173137500Sjulian                    if (!types.isSameType(tParam, inferenceContext().asUndetVar(sParam))) {
1174137500Sjulian                        return false;
1175137500Sjulian                    }
1176137500Sjulian                    tParams = tParams.tail;
1177166279Sariff                    sParams = sParams.tail;
1178137500Sjulian                }
1179166279Sariff                if (!tParams.isEmpty() || !sParams.isEmpty()) {
1180137500Sjulian                    return false;
118165543Scg                }
1182137500Sjulian
118365543Scg                // compare returns
1184137500Sjulian                Type tRet = tDesc.getReturnType();
1185137500Sjulian                Type sRet = types.subst(sDesc.getReturnType(), sTypeParams, tTypeParams);
1186137500Sjulian                if (tRet.containsAny(tTypeParams) && inferenceContext().free(sRet)) {
1187137500Sjulian                    return false;
1188137500Sjulian                }
1189137500Sjulian                MostSpecificFunctionReturnChecker msc = new MostSpecificFunctionReturnChecker(tRet, sRet);
1190137500Sjulian                msc.scan(tree);
1191137500Sjulian                return msc.result;
1192137500Sjulian            }
1193137500Sjulian
1194137500Sjulian            /**
119565543Scg             * Tests whether one functional interface type can be considered more specific
1196166279Sariff             * than another unrelated functional interface type for the scanned expression.
1197137500Sjulian             */
1198137500Sjulian            class MostSpecificFunctionReturnChecker extends DeferredAttr.PolyScanner {
1199137500Sjulian
1200137500Sjulian                final Type tRet;
1201137500Sjulian                final Type sRet;
1202137500Sjulian                boolean result;
1203137500Sjulian
1204137500Sjulian                /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
1205137500Sjulian                MostSpecificFunctionReturnChecker(Type tRet, Type sRet) {
1206137500Sjulian                    this.tRet = tRet;
1207137500Sjulian                    this.sRet = sRet;
1208137500Sjulian                    result = true;
1209137500Sjulian                }
121065543Scg
121165543Scg                @Override
121265543Scg                void skip(JCTree tree) {
121365543Scg                    result &= false;
121465543Scg                }
121565543Scg
1216137500Sjulian                @Override
121765543Scg                public void visitConditional(JCConditional tree) {
121865543Scg                    scan(asExpr(tree.truepart));
121965543Scg                    scan(asExpr(tree.falsepart));
1220137500Sjulian                }
1221137500Sjulian
1222137500Sjulian                @Override
1223137500Sjulian                public void visitReference(JCMemberReference tree) {
1224137500Sjulian                    if (sRet.hasTag(VOID)) {
122565543Scg                        result &= true;
1226137500Sjulian                    } else if (tRet.hasTag(VOID)) {
122765543Scg                        result &= false;
122865543Scg                    } else if (tRet.isPrimitive() != sRet.isPrimitive()) {
122965543Scg                        boolean retValIsPrimitive =
123065543Scg                                tree.refPolyKind == PolyKind.STANDALONE &&
123165543Scg                                tree.sym.type.getReturnType().isPrimitive();
123265543Scg                        result &= (retValIsPrimitive == tRet.isPrimitive()) &&
123365543Scg                                  (retValIsPrimitive != sRet.isPrimitive());
1234137500Sjulian                    } else {
1235137500Sjulian                        result &= compatibleBySubtyping(tRet, sRet);
1236137500Sjulian                    }
1237137500Sjulian                }
1238137500Sjulian
1239137500Sjulian                @Override
1240137500Sjulian                public void visitParens(JCParens tree) {
1241137500Sjulian                    scan(asExpr(tree.expr));
1242137500Sjulian                }
1243137500Sjulian
1244137500Sjulian                @Override
1245137500Sjulian                public void visitLambda(JCLambda tree) {
1246137500Sjulian                    if (sRet.hasTag(VOID)) {
1247137500Sjulian                        result &= true;
1248137500Sjulian                    } else if (tRet.hasTag(VOID)) {
1249137500Sjulian                        result &= false;
1250154067Sariff                    } else {
1251137500Sjulian                        List<JCExpression> lambdaResults = lambdaResults(tree);
1252154067Sariff                        if (!lambdaResults.isEmpty() && unrelatedFunctionalInterfaces(tRet, sRet)) {
1253137500Sjulian                            for (JCExpression expr : lambdaResults) {
1254137500Sjulian                                result &= functionalInterfaceMostSpecific(tRet, sRet, expr);
1255137500Sjulian                            }
1256137500Sjulian                        } else if (!lambdaResults.isEmpty() && tRet.isPrimitive() != sRet.isPrimitive()) {
1257137500Sjulian                            for (JCExpression expr : lambdaResults) {
1258137500Sjulian                                boolean retValIsPrimitive = expr.isStandalone() && expr.type.isPrimitive();
1259137500Sjulian                                result &= (retValIsPrimitive == tRet.isPrimitive()) &&
1260137500Sjulian                                        (retValIsPrimitive != sRet.isPrimitive());
1261137500Sjulian                            }
1262154067Sariff                        } else {
1263137500Sjulian                            result &= compatibleBySubtyping(tRet, sRet);
1264154067Sariff                        }
1265137500Sjulian                    }
1266137500Sjulian                }
1267137500Sjulian                //where
1268137500Sjulian
1269137500Sjulian                private List<JCExpression> lambdaResults(JCLambda lambda) {
1270137500Sjulian                    if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) {
1271137500Sjulian                        return List.of(asExpr((JCExpression) lambda.body));
1272137500Sjulian                    } else {
1273193640Sariff                        final ListBuffer<JCExpression> buffer = new ListBuffer<>();
1274137500Sjulian                        DeferredAttr.LambdaReturnScanner lambdaScanner =
1275137500Sjulian                                new DeferredAttr.LambdaReturnScanner() {
1276137500Sjulian                                    @Override
1277137500Sjulian                                    public void visitReturn(JCReturn tree) {
1278137500Sjulian                                        if (tree.expr != null) {
1279137500Sjulian                                            buffer.append(asExpr(tree.expr));
1280137500Sjulian                                        }
1281137500Sjulian                                    }
128265543Scg                                };
1283166279Sariff                        lambdaScanner.scan(lambda.body);
1284166279Sariff                        return buffer.toList();
128565543Scg                    }
128665543Scg                }
128765543Scg
128865543Scg                private JCExpression asExpr(JCExpression expr) {
128970291Scg                    if (expr.type.hasTag(DEFERRED)) {
129065543Scg                        JCTree speculativeTree = ((DeferredType)expr.type).speculativeTree(deferredAttrContext);
1291137500Sjulian                        if (speculativeTree != deferredAttr.stuckTree) {
1292137500Sjulian                            expr = (JCExpression)speculativeTree;
1293137500Sjulian                        }
129465543Scg                    }
129565543Scg                    return expr;
129665543Scg                }
129765543Scg            }
129865543Scg
129965543Scg        }
1300137500Sjulian
1301137500Sjulian        public MethodCheck mostSpecificCheck(List<Type> actuals) {
1302137500Sjulian            Assert.error("Cannot get here!");
1303137500Sjulian            return null;
1304137500Sjulian        }
1305137500Sjulian    }
130684658Scg
1307137500Sjulian    public static class InapplicableMethodException extends RuntimeException {
1308137500Sjulian        private static final long serialVersionUID = 0;
1309137500Sjulian
131065543Scg        JCDiagnostic diagnostic;
1311137500Sjulian        JCDiagnostic.Factory diags;
1312137500Sjulian
131365543Scg        InapplicableMethodException(JCDiagnostic.Factory diags) {
1314137500Sjulian            this.diagnostic = null;
1315137500Sjulian            this.diags = diags;
1316137500Sjulian        }
1317137500Sjulian        InapplicableMethodException setMessage() {
1318137500Sjulian            return setMessage((JCDiagnostic)null);
1319137500Sjulian        }
132065543Scg        InapplicableMethodException setMessage(String key) {
1321137500Sjulian            return setMessage(key != null ? diags.fragment(key) : null);
1322137500Sjulian        }
1323137500Sjulian        InapplicableMethodException setMessage(String key, Object... args) {
1324137500Sjulian            return setMessage(key != null ? diags.fragment(key, args) : null);
1325137500Sjulian        }
1326137500Sjulian        InapplicableMethodException setMessage(JCDiagnostic diag) {
1327137500Sjulian            this.diagnostic = diag;
1328137500Sjulian            return this;
1329137500Sjulian        }
1330137500Sjulian
1331137500Sjulian        public JCDiagnostic getDiagnostic() {
1332137500Sjulian            return diagnostic;
1333137500Sjulian        }
1334137500Sjulian    }
1335137500Sjulian    private final InapplicableMethodException inapplicableMethodException;
1336137500Sjulian
1337137500Sjulian/* ***************************************************************************
1338137500Sjulian *  Symbol lookup
1339137500Sjulian *  the following naming conventions for arguments are used
1340137500Sjulian *
1341137500Sjulian *       env      is the environment where the symbol was mentioned
1342137500Sjulian *       site     is the type of which the symbol is a member
1343137500Sjulian *       name     is the symbol's name
1344137500Sjulian *                if no arguments are given
1345137500Sjulian *       argtypes are the value arguments, if we search for a method
1346137500Sjulian *
1347137500Sjulian *  If no symbol was found, a ResolveError detailing the problem is returned.
1348137500Sjulian ****************************************************************************/
1349137500Sjulian
1350137500Sjulian    /** Find field. Synthetic fields are always skipped.
1351137500Sjulian     *  @param env     The current environment.
1352137500Sjulian     *  @param site    The original type from where the selection takes place.
1353137500Sjulian     *  @param name    The name of the field.
135465543Scg     *  @param c       The class to search for the field. This is always
135565543Scg     *                 a superclass or implemented interface of site's class.
135665543Scg     */
1357137500Sjulian    Symbol findField(Env<AttrContext> env,
135865543Scg                     Type site,
1359137500Sjulian                     Name name,
1360137500Sjulian                     TypeSymbol c) {
1361137500Sjulian        while (c.type.hasTag(TYPEVAR))
1362137500Sjulian            c = c.type.getUpperBound().tsym;
1363137500Sjulian        Symbol bestSoFar = varNotFound;
1364137500Sjulian        Symbol sym;
136565543Scg        for (Symbol s : c.members().getSymbolsByName(name)) {
136665543Scg            if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
136765543Scg                return isAccessible(env, site, s)
136865543Scg                    ? s : new AccessError(env, site, s);
136965543Scg            }
1370137500Sjulian        }
137165543Scg        Type st = types.supertype(c.type);
137265543Scg        if (st != null && (st.hasTag(CLASS) || st.hasTag(TYPEVAR))) {
137365543Scg            sym = findField(env, site, name, st.tsym);
1374137500Sjulian            bestSoFar = bestOf(bestSoFar, sym);
1375137500Sjulian        }
1376137500Sjulian        for (List<Type> l = types.interfaces(c.type);
1377193640Sariff             bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
1378137500Sjulian             l = l.tail) {
137965543Scg            sym = findField(env, site, name, l.head.tsym);
138065543Scg            if (bestSoFar.exists() && sym.exists() &&
138165543Scg                sym.owner != bestSoFar.owner)
1382137500Sjulian                bestSoFar = new AmbiguityError(bestSoFar, sym);
1383137500Sjulian            else
1384137500Sjulian                bestSoFar = bestOf(bestSoFar, sym);
138589887Sscottl        }
138665543Scg        return bestSoFar;
138765543Scg    }
1388193640Sariff
1389137500Sjulian    /** Resolve a field identifier, throw a fatal error if not found.
139065543Scg     *  @param pos       The position to use for error reporting.
1391193640Sariff     *  @param env       The environment current at the method invocation.
1392193640Sariff     *  @param site      The type of the qualifying expression, in which
1393193640Sariff     *                   identifier is searched.
1394193640Sariff     *  @param name      The identifier's name.
139565543Scg     */
139665543Scg    public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env,
1397193640Sariff                                          Type site, Name name) {
1398137500Sjulian        Symbol sym = findField(env, site, name, site.tsym);
139965543Scg        if (sym.kind == VAR) return (VarSymbol)sym;
1400137500Sjulian        else throw new FatalError(
1401137500Sjulian                 diags.fragment("fatal.err.cant.locate.field",
1402137500Sjulian                                name));
1403137500Sjulian    }
1404137500Sjulian
1405137500Sjulian    /** Find unqualified variable or field with given name.
1406137500Sjulian     *  Synthetic fields always skipped.
1407137500Sjulian     *  @param env     The current environment.
1408137500Sjulian     *  @param name    The name of the variable or field.
1409137500Sjulian     */
1410137500Sjulian    Symbol findVar(Env<AttrContext> env, Name name) {
1411137500Sjulian        Symbol bestSoFar = varNotFound;
1412137500Sjulian        Env<AttrContext> env1 = env;
1413137500Sjulian        boolean staticOnly = false;
1414137500Sjulian        while (env1.outer != null) {
1415137500Sjulian            Symbol sym = null;
1416137500Sjulian            if (isStatic(env1)) staticOnly = true;
1417137500Sjulian            for (Symbol s : env1.info.scope.getSymbolsByName(name)) {
1418137500Sjulian                if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
141965543Scg                    sym = s;
142065543Scg                    break;
142165543Scg                }
1422137500Sjulian            }
142365543Scg            if (sym == null) {
142465543Scg                sym = findField(env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
142565543Scg            }
142665543Scg            if (sym.exists()) {
142765543Scg                if (staticOnly &&
1428137500Sjulian                    sym.kind == VAR &&
142965543Scg                    sym.owner.kind == TYP &&
1430137500Sjulian                    (sym.flags() & STATIC) == 0)
143165543Scg                    return new StaticError(sym);
143265543Scg                else
143365543Scg                    return sym;
1434137500Sjulian            } else {
143565543Scg                bestSoFar = bestOf(bestSoFar, sym);
143665543Scg            }
143765543Scg
143865543Scg            if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
143965543Scg            env1 = env1.outer;
1440193640Sariff        }
1441137500Sjulian
144265543Scg        Symbol sym = findField(env, syms.predefClass.type, name, syms.predefClass);
144365543Scg        if (sym.exists())
1444193640Sariff            return sym;
144565543Scg        if (bestSoFar.exists())
1446137500Sjulian            return bestSoFar;
1447137500Sjulian
1448137500Sjulian        Symbol origin = null;
144965543Scg        for (Scope sc : new Scope[] { env.toplevel.namedImportScope, env.toplevel.starImportScope }) {
1450137500Sjulian            for (Symbol currentSymbol : sc.getSymbolsByName(name)) {
1451137500Sjulian                if (currentSymbol.kind != VAR)
1452137500Sjulian                    continue;
145365543Scg                // invariant: sym.kind == Symbol.Kind.VAR
145465543Scg                if (!bestSoFar.kind.isResolutionError() &&
145574763Scg                    currentSymbol.owner != bestSoFar.owner)
1456137500Sjulian                    return new AmbiguityError(bestSoFar, currentSymbol);
145765543Scg                else if (!bestSoFar.kind.betterThan(VAR)) {
145865543Scg                    origin = sc.getOrigin(currentSymbol).owner;
1459193640Sariff                    bestSoFar = isAccessible(env, origin.type, currentSymbol)
1460193640Sariff                        ? currentSymbol : new AccessError(env, origin.type, currentSymbol);
1461193640Sariff                }
1462193640Sariff            }
1463193640Sariff            if (bestSoFar.exists()) break;
1464193640Sariff        }
146565543Scg        if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type)
146665543Scg            return bestSoFar.clone(origin);
1467154241Sariff        else
146865543Scg            return bestSoFar;
1469137500Sjulian    }
1470137500Sjulian
1471137500Sjulian    Warner noteWarner = new Warner();
1472137500Sjulian
1473137500Sjulian    /** Select the best method for a call site among two choices.
1474137500Sjulian     *  @param env              The current environment.
1475137500Sjulian     *  @param site             The original type from where the
1476137500Sjulian     *                          selection takes place.
1477137500Sjulian     *  @param argtypes         The invocation's value arguments,
1478137500Sjulian     *  @param typeargtypes     The invocation's type arguments,
1479137500Sjulian     *  @param sym              Proposed new best match.
1480137500Sjulian     *  @param bestSoFar        Previously found best match.
1481137500Sjulian     *  @param allowBoxing Allow boxing conversions of arguments.
1482193640Sariff     *  @param useVarargs Box trailing arguments into an array for varargs.
1483137500Sjulian     */
1484137500Sjulian    @SuppressWarnings("fallthrough")
1485137500Sjulian    Symbol selectBest(Env<AttrContext> env,
1486137500Sjulian                      Type site,
1487137500Sjulian                      List<Type> argtypes,
1488137500Sjulian                      List<Type> typeargtypes,
1489137500Sjulian                      Symbol sym,
1490137500Sjulian                      Symbol bestSoFar,
1491137500Sjulian                      boolean allowBoxing,
1492166279Sariff                      boolean useVarargs) {
1493166279Sariff        if (sym.kind == ERR ||
1494137500Sjulian                !sym.isInheritedIn(site.tsym, types)) {
1495137500Sjulian            return bestSoFar;
1496137500Sjulian        } else if (useVarargs && (sym.flags() & VARARGS) == 0) {
1497137500Sjulian            return bestSoFar.kind.isResolutionError() ?
1498137500Sjulian                    new BadVarargsMethod((ResolveError)bestSoFar.baseSymbol()) :
1499137500Sjulian                    bestSoFar;
1500137500Sjulian        }
1501137500Sjulian        Assert.check(!sym.kind.isResolutionError());
1502137500Sjulian        try {
1503137500Sjulian            types.noWarnings.clear();
1504137500Sjulian            Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes,
1505137500Sjulian                               allowBoxing, useVarargs, types.noWarnings);
1506137500Sjulian            currentResolutionContext.addApplicableCandidate(sym, mt);
1507137500Sjulian        } catch (InapplicableMethodException ex) {
1508137500Sjulian            currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic());
1509137500Sjulian            switch (bestSoFar.kind) {
1510137500Sjulian                case ABSENT_MTH:
1511137500Sjulian                    return new InapplicableSymbolError(currentResolutionContext);
1512137500Sjulian                case WRONG_MTH:
1513137500Sjulian                    bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
1514137500Sjulian                default:
1515137500Sjulian                    return bestSoFar;
1516137500Sjulian            }
1517137500Sjulian        }
1518137500Sjulian        if (!isAccessible(env, site, sym)) {
1519137500Sjulian            return (bestSoFar.kind == ABSENT_MTH)
1520137500Sjulian                ? new AccessError(env, site, sym)
1521137500Sjulian                : bestSoFar;
1522137500Sjulian        }
1523137500Sjulian        return (bestSoFar.kind.isResolutionError() && bestSoFar.kind != AMBIGUOUS)
1524137500Sjulian            ? sym
1525137500Sjulian            : mostSpecific(argtypes, sym, bestSoFar, env, site, useVarargs);
1526137500Sjulian    }
1527137500Sjulian
1528137500Sjulian    /* Return the most specific of the two methods for a call,
1529193640Sariff     *  given that both are accessible and applicable.
1530137500Sjulian     *  @param m1               A new candidate for most specific.
1531137500Sjulian     *  @param m2               The previous most specific candidate.
1532137500Sjulian     *  @param env              The current environment.
1533137500Sjulian     *  @param site             The original type from where the selection
1534137500Sjulian     *                          takes place.
1535137500Sjulian     *  @param allowBoxing Allow boxing conversions of arguments.
1536193640Sariff     *  @param useVarargs Box trailing arguments into an array for varargs.
1537137500Sjulian     */
1538137500Sjulian    Symbol mostSpecific(List<Type> argtypes, Symbol m1,
1539193640Sariff                        Symbol m2,
1540193640Sariff                        Env<AttrContext> env,
1541193640Sariff                        final Type site,
1542193640Sariff                        boolean useVarargs) {
1543137500Sjulian        switch (m2.kind) {
1544137500Sjulian        case MTH:
1545193640Sariff            if (m1 == m2) return m1;
1546137500Sjulian            boolean m1SignatureMoreSpecific =
1547137500Sjulian                    signatureMoreSpecific(argtypes, env, site, m1, m2, useVarargs);
1548137500Sjulian            boolean m2SignatureMoreSpecific =
1549137500Sjulian                    signatureMoreSpecific(argtypes, env, site, m2, m1, useVarargs);
1550137500Sjulian            if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) {
1551137500Sjulian                Type mt1 = types.memberType(site, m1);
1552137500Sjulian                Type mt2 = types.memberType(site, m2);
1553137500Sjulian                if (!types.overrideEquivalent(mt1, mt2))
1554137500Sjulian                    return ambiguityError(m1, m2);
1555137500Sjulian
1556137500Sjulian                // same signature; select (a) the non-bridge method, or
1557137500Sjulian                // (b) the one that overrides the other, or (c) the concrete
1558137500Sjulian                // one, or (d) merge both abstract signatures
1559137500Sjulian                if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE))
1560137500Sjulian                    return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
1561137500Sjulian
1562137500Sjulian                // if one overrides or hides the other, use it
1563137500Sjulian                TypeSymbol m1Owner = (TypeSymbol)m1.owner;
1564137500Sjulian                TypeSymbol m2Owner = (TypeSymbol)m2.owner;
1565137500Sjulian                if (types.asSuper(m1Owner.type, m2Owner) != null &&
1566137500Sjulian                    ((m1.owner.flags_field & INTERFACE) == 0 ||
1567137500Sjulian                     (m2.owner.flags_field & INTERFACE) != 0) &&
1568137500Sjulian                    m1.overrides(m2, m1Owner, types, false))
1569137500Sjulian                    return m1;
1570137500Sjulian                if (types.asSuper(m2Owner.type, m1Owner) != null &&
1571137500Sjulian                    ((m2.owner.flags_field & INTERFACE) == 0 ||
1572137500Sjulian                     (m1.owner.flags_field & INTERFACE) != 0) &&
1573137500Sjulian                    m2.overrides(m1, m2Owner, types, false))
1574137500Sjulian                    return m2;
1575137500Sjulian                boolean m1Abstract = (m1.flags() & ABSTRACT) != 0;
1576137500Sjulian                boolean m2Abstract = (m2.flags() & ABSTRACT) != 0;
1577137500Sjulian                if (m1Abstract && !m2Abstract) return m2;
1578137500Sjulian                if (m2Abstract && !m1Abstract) return m1;
1579137500Sjulian                // both abstract or both concrete
1580137500Sjulian                return ambiguityError(m1, m2);
1581137500Sjulian            }
1582137500Sjulian            if (m1SignatureMoreSpecific) return m1;
1583137500Sjulian            if (m2SignatureMoreSpecific) return m2;
1584137500Sjulian            return ambiguityError(m1, m2);
1585137500Sjulian        case AMBIGUOUS:
1586137500Sjulian            //compare m1 to ambiguous methods in m2
1587137500Sjulian            AmbiguityError e = (AmbiguityError)m2.baseSymbol();
1588137500Sjulian            boolean m1MoreSpecificThanAnyAmbiguous = true;
1589137500Sjulian            boolean allAmbiguousMoreSpecificThanM1 = true;
1590137500Sjulian            for (Symbol s : e.ambiguousSyms) {
1591137500Sjulian                Symbol moreSpecific = mostSpecific(argtypes, m1, s, env, site, useVarargs);
1592193640Sariff                m1MoreSpecificThanAnyAmbiguous &= moreSpecific == m1;
1593137500Sjulian                allAmbiguousMoreSpecificThanM1 &= moreSpecific == s;
1594137500Sjulian            }
1595137500Sjulian            if (m1MoreSpecificThanAnyAmbiguous)
1596137500Sjulian                return m1;
1597137500Sjulian            //if m1 is more specific than some ambiguous methods, but other ambiguous methods are
1598137500Sjulian            //more specific than m1, add it as a new ambiguous method:
1599137500Sjulian            if (!allAmbiguousMoreSpecificThanM1)
1600137500Sjulian                e.addAmbiguousSymbol(m1);
1601137500Sjulian            return e;
1602137500Sjulian        default:
160365543Scg            throw new AssertionError();
1604193640Sariff        }
1605193640Sariff    }
160665543Scg    //where
160765543Scg    private boolean signatureMoreSpecific(List<Type> actuals, Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean useVarargs) {
1608137500Sjulian        noteWarner.clear();
160965543Scg        int maxLength = Math.max(
1610137500Sjulian                            Math.max(m1.type.getParameterTypes().length(), actuals.length()),
161165543Scg                            m2.type.getParameterTypes().length());
161265543Scg        MethodResolutionContext prevResolutionContext = currentResolutionContext;
1613137500Sjulian        try {
1614137500Sjulian            currentResolutionContext = new MethodResolutionContext();
1615137500Sjulian            currentResolutionContext.step = prevResolutionContext.step;
1616137500Sjulian            currentResolutionContext.methodCheck =
1617137500Sjulian                    prevResolutionContext.methodCheck.mostSpecificCheck(actuals);
1618137500Sjulian            Type mst = instantiate(env, site, m2, null,
1619137500Sjulian                    adjustArgs(types.cvarLowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null,
1620137500Sjulian                    false, useVarargs, noteWarner);
1621137500Sjulian            return mst != null &&
1622193640Sariff                    !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
162370134Scg        } finally {
1624137500Sjulian            currentResolutionContext = prevResolutionContext;
162565543Scg        }
1626137500Sjulian    }
162765543Scg
162865543Scg    List<Type> adjustArgs(List<Type> args, Symbol msym, int length, boolean allowVarargs) {
162965543Scg        if ((msym.flags() & VARARGS) != 0 && allowVarargs) {
163065543Scg            Type varargsElem = types.elemtype(args.last());
163165543Scg            if (varargsElem == null) {
163265543Scg                Assert.error("Bad varargs = " + args.last() + " " + msym);
163365543Scg            }
163465543Scg            List<Type> newArgs = args.reverse().tail.prepend(varargsElem).reverse();
1635137500Sjulian            while (newArgs.length() < length) {
163665543Scg                newArgs = newArgs.append(newArgs.last());
1637137500Sjulian            }
163865543Scg            return newArgs;
1639137500Sjulian        } else {
164065543Scg            return args;
164165543Scg        }
164265543Scg    }
1643137500Sjulian    //where
1644137500Sjulian    Type mostSpecificReturnType(Type mt1, Type mt2) {
164570619Sjhb        Type rt1 = mt1.getReturnType();
1646137500Sjulian        Type rt2 = mt2.getReturnType();
1647137500Sjulian
1648137500Sjulian        if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL)) {
1649137500Sjulian            //if both are generic methods, adjust return type ahead of subtyping check
1650137500Sjulian            rt1 = types.subst(rt1, mt1.getTypeArguments(), mt2.getTypeArguments());
1651137500Sjulian        }
1652137500Sjulian        //first use subtyping, then return type substitutability
1653137500Sjulian        if (types.isSubtype(rt1, rt2)) {
1654137500Sjulian            return mt1;
1655137500Sjulian        } else if (types.isSubtype(rt2, rt1)) {
1656137500Sjulian            return mt2;
1657137500Sjulian        } else if (types.returnTypeSubstitutable(mt1, mt2)) {
1658137500Sjulian            return mt1;
1659137500Sjulian        } else if (types.returnTypeSubstitutable(mt2, mt1)) {
1660137500Sjulian            return mt2;
1661137500Sjulian        } else {
1662137500Sjulian            return null;
1663137500Sjulian        }
1664137500Sjulian    }
1665137500Sjulian    //where
1666137500Sjulian    Symbol ambiguityError(Symbol m1, Symbol m2) {
1667137500Sjulian        if (((m1.flags() | m2.flags()) & CLASH) != 0) {
1668137500Sjulian            return (m1.flags() & CLASH) == 0 ? m1 : m2;
1669137500Sjulian        } else {
1670137500Sjulian            return new AmbiguityError(m1, m2);
1671137500Sjulian        }
1672137500Sjulian    }
1673137500Sjulian
1674137500Sjulian    Symbol findMethodInScope(Env<AttrContext> env,
1675137500Sjulian            Type site,
1676137500Sjulian            Name name,
1677137500Sjulian            List<Type> argtypes,
1678137500Sjulian            List<Type> typeargtypes,
1679137500Sjulian            Scope sc,
1680137500Sjulian            Symbol bestSoFar,
168165543Scg            boolean allowBoxing,
1682137500Sjulian            boolean useVarargs,
168370619Sjhb            boolean abstractok) {
1684137500Sjulian        for (Symbol s : sc.getSymbolsByName(name, new LookupFilter(abstractok))) {
1685137500Sjulian            bestSoFar = selectBest(env, site, argtypes, typeargtypes, s,
1686137500Sjulian                    bestSoFar, allowBoxing, useVarargs);
1687137500Sjulian        }
1688137500Sjulian        return bestSoFar;
168970619Sjhb    }
169070619Sjhb    //where
169170945Sjhb        class LookupFilter implements Filter<Symbol> {
169270619Sjhb
169370619Sjhb            boolean abstractOk;
169470945Sjhb
169570619Sjhb            LookupFilter(boolean abstractOk) {
169670619Sjhb                this.abstractOk = abstractOk;
169770619Sjhb            }
169870619Sjhb
1699137500Sjulian            public boolean accepts(Symbol s) {
1700137500Sjulian                long flags = s.flags();
1701137500Sjulian                return s.kind == MTH &&
1702137500Sjulian                        (flags & SYNTHETIC) == 0 &&
1703137500Sjulian                        (abstractOk ||
1704137500Sjulian                        (flags & DEFAULT) != 0 ||
1705137500Sjulian                        (flags & ABSTRACT) == 0);
170665543Scg            }
170765543Scg        }
170865543Scg
170965543Scg    /** Find best qualified method matching given name, type and value
171065543Scg     *  arguments.
171165543Scg     *  @param env       The current environment.
171265543Scg     *  @param site      The original type from where the selection
171365543Scg     *                   takes place.
171465543Scg     *  @param name      The method's name.
171565543Scg     *  @param argtypes  The method's value arguments.
171665543Scg     *  @param typeargtypes The method's type arguments
171765543Scg     *  @param allowBoxing Allow boxing conversions of arguments.
171865543Scg     *  @param useVarargs Box trailing arguments into an array for varargs.
171965543Scg     */
172065543Scg    Symbol findMethod(Env<AttrContext> env,
172165543Scg                      Type site,
172265543Scg                      Name name,
172365543Scg                      List<Type> argtypes,
172465543Scg                      List<Type> typeargtypes,
1725137500Sjulian                      boolean allowBoxing,
172665543Scg                      boolean useVarargs) {
172765543Scg        Symbol bestSoFar = methodNotFound;
172865543Scg        bestSoFar = findMethod(env,
172965543Scg                          site,
1730137500Sjulian                          name,
173165543Scg                          argtypes,
1732137500Sjulian                          typeargtypes,
1733137500Sjulian                          site.tsym.type,
1734137500Sjulian                          bestSoFar,
173565543Scg                          allowBoxing,
173665543Scg                          useVarargs);
173765543Scg        return bestSoFar;
173865543Scg    }
173965543Scg    // where
174065543Scg    private Symbol findMethod(Env<AttrContext> env,
1741137500Sjulian                              Type site,
174265543Scg                              Name name,
1743137500Sjulian                              List<Type> argtypes,
174465543Scg                              List<Type> typeargtypes,
174565543Scg                              Type intype,
174665543Scg                              Symbol bestSoFar,
174765543Scg                              boolean allowBoxing,
174865543Scg                              boolean useVarargs) {
174965543Scg        @SuppressWarnings({"unchecked","rawtypes"})
175065543Scg        List<Type>[] itypes = (List<Type>[])new List[] { List.<Type>nil(), List.<Type>nil() };
175165543Scg
175265543Scg        InterfaceLookupPhase iphase = InterfaceLookupPhase.ABSTRACT_OK;
175365543Scg        for (TypeSymbol s : superclasses(intype)) {
175465543Scg            bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
175565543Scg                    s.members(), bestSoFar, allowBoxing, useVarargs, true);
175665543Scg            if (name == names.init) return bestSoFar;
175765543Scg            iphase = (iphase == null) ? null : iphase.update(s, this);
175865543Scg            if (iphase != null) {
175965543Scg                for (Type itype : types.interfaces(s.type)) {
176065543Scg                    itypes[iphase.ordinal()] = types.union(types.closure(itype), itypes[iphase.ordinal()]);
176165543Scg                }
176265543Scg            }
176365543Scg        }
176465543Scg
176565543Scg        Symbol concrete = bestSoFar.kind.isValid() &&
176665543Scg                (bestSoFar.flags() & ABSTRACT) == 0 ?
1767142890Simp                bestSoFar : methodNotFound;
176865543Scg
176965543Scg        for (InterfaceLookupPhase iphase2 : InterfaceLookupPhase.values()) {
177065543Scg            //keep searching for abstract methods
177165543Scg            for (Type itype : itypes[iphase2.ordinal()]) {
177265543Scg                if (!itype.isInterface()) continue; //skip j.l.Object (included by Types.closure())
177365543Scg                if (iphase2 == InterfaceLookupPhase.DEFAULT_OK &&
177465543Scg                        (itype.tsym.flags() & DEFAULT) == 0) continue;
177565543Scg                bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
177665543Scg                        itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, true);
1777119690Sjhb                if (concrete != bestSoFar &&
177865543Scg                    concrete.kind.isValid() &&
177965543Scg                    bestSoFar.kind.isValid() &&
178065543Scg                        types.isSubSignature(concrete.type, bestSoFar.type)) {
178165543Scg                    //this is an hack - as javac does not do full membership checks
178265543Scg                    //most specific ends up comparing abstract methods that might have
178365543Scg                    //been implemented by some concrete method in a subclass and,
1784174582Sariff                    //because of raw override, it is possible for an abstract method
178565543Scg                    //to be more specific than the concrete method - so we need
1786170873Sariff                    //to explicitly call that out (see CR 6178365)
178765543Scg                    bestSoFar = concrete;
178865543Scg                }
1789167608Sariff            }
1790137500Sjulian        }
1791137500Sjulian        return bestSoFar;
1792137500Sjulian    }
1793137500Sjulian
1794137500Sjulian    enum InterfaceLookupPhase {
1795137500Sjulian        ABSTRACT_OK() {
1796137500Sjulian            @Override
1797174582Sariff            InterfaceLookupPhase update(Symbol s, Resolve rs) {
1798174582Sariff                //We should not look for abstract methods if receiver is a concrete class
1799174582Sariff                //(as concrete classes are expected to implement all abstracts coming
1800174582Sariff                //from superinterfaces)
1801174582Sariff                if ((s.flags() & (ABSTRACT | INTERFACE | ENUM)) != 0) {
1802174582Sariff                    return this;
1803174582Sariff                } else {
1804174582Sariff                    return DEFAULT_OK;
1805174582Sariff                }
180684658Scg            }
1807166904Snetchild        },
1808137500Sjulian        DEFAULT_OK() {
1809137500Sjulian            @Override
1810137500Sjulian            InterfaceLookupPhase update(Symbol s, Resolve rs) {
1811137500Sjulian                return this;
1812137500Sjulian            }
1813137500Sjulian        };
1814137500Sjulian
1815137500Sjulian        abstract InterfaceLookupPhase update(Symbol s, Resolve rs);
1816137500Sjulian    }
1817137500Sjulian
1818137500Sjulian    /**
1819137500Sjulian     * Return an Iterable object to scan the superclasses of a given type.
1820137500Sjulian     * It's crucial that the scan is done lazily, as we don't want to accidentally
182184658Scg     * access more supertypes than strictly needed (as this could trigger completion
1822166904Snetchild     * errors if some of the not-needed supertypes are missing/ill-formed).
1823137500Sjulian     */
1824137500Sjulian    Iterable<TypeSymbol> superclasses(final Type intype) {
1825137500Sjulian        return new Iterable<TypeSymbol>() {
1826137500Sjulian            public Iterator<TypeSymbol> iterator() {
1827137500Sjulian                return new Iterator<TypeSymbol>() {
1828137500Sjulian
1829137500Sjulian                    List<TypeSymbol> seen = List.nil();
1830137500Sjulian                    TypeSymbol currentSym = symbolFor(intype);
1831137500Sjulian                    TypeSymbol prevSym = null;
1832137500Sjulian
183365543Scg                    public boolean hasNext() {
1834137500Sjulian                        if (currentSym == syms.noSymbol) {
183565543Scg                            currentSym = symbolFor(types.supertype(prevSym.type));
183665543Scg                        }
183765543Scg                        return currentSym != null;
1838137500Sjulian                    }
1839137500Sjulian
184065543Scg                    public TypeSymbol next() {
1841137500Sjulian                        prevSym = currentSym;
1842137500Sjulian                        currentSym = syms.noSymbol;
184365543Scg                        Assert.check(prevSym != null || prevSym != syms.noSymbol);
184465543Scg                        return prevSym;
184565543Scg                    }
1846137500Sjulian
1847137500Sjulian                    public void remove() {
184865543Scg                        throw new UnsupportedOperationException();
1849137500Sjulian                    }
1850137500Sjulian
1851137500Sjulian                    TypeSymbol symbolFor(Type t) {
185265543Scg                        if (!t.hasTag(CLASS) &&
1853254306Sscottl                                !t.hasTag(TYPEVAR)) {
185465543Scg                            return null;
1855137500Sjulian                        }
1856254306Sscottl                        t = types.skipTypeVars(t, false);
1857137500Sjulian                        if (seen.contains(t.tsym)) {
1858137500Sjulian                            //degenerate case in which we have a circular
1859137500Sjulian                            //class hierarchy - because of ill-formed classfiles
1860137500Sjulian                            return null;
1861137500Sjulian                        }
1862137500Sjulian                        seen = seen.prepend(t.tsym);
186365543Scg                        return t.tsym;
1864137500Sjulian                    }
186565543Scg                };
186665543Scg            }
1867141095Simp        };
1868141095Simp    }
1869137500Sjulian
1870137500Sjulian    /** Find unqualified method matching given name, type and value arguments.
1871137500Sjulian     *  @param env       The current environment.
1872137500Sjulian     *  @param name      The method's name.
1873137500Sjulian     *  @param argtypes  The method's value arguments.
1874137500Sjulian     *  @param typeargtypes  The method's type arguments.
1875137500Sjulian     *  @param allowBoxing Allow boxing conversions of arguments.
1876137500Sjulian     *  @param useVarargs Box trailing arguments into an array for varargs.
187765543Scg     */
1878137500Sjulian    Symbol findFun(Env<AttrContext> env, Name name,
1879137500Sjulian                   List<Type> argtypes, List<Type> typeargtypes,
1880137500Sjulian                   boolean allowBoxing, boolean useVarargs) {
1881137500Sjulian        Symbol bestSoFar = methodNotFound;
1882137500Sjulian        Env<AttrContext> env1 = env;
1883137500Sjulian        boolean staticOnly = false;
1884137500Sjulian        while (env1.outer != null) {
1885137500Sjulian            if (isStatic(env1)) staticOnly = true;
1886137500Sjulian            Assert.check(env1.info.preferredTreeForDiagnostics == null);
1887137500Sjulian            env1.info.preferredTreeForDiagnostics = env.tree;
1888137500Sjulian            try {
1889137500Sjulian                Symbol sym = findMethod(
1890137500Sjulian                    env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
1891154067Sariff                    allowBoxing, useVarargs);
189265543Scg                if (sym.exists()) {
1893137500Sjulian                    if (staticOnly &&
189465543Scg                        sym.kind == MTH &&
189565543Scg                        sym.owner.kind == TYP &&
1896154067Sariff                        (sym.flags() & STATIC) == 0) return new StaticError(sym);
189770134Scg                    else return sym;
1898137500Sjulian                } else {
1899137500Sjulian                    bestSoFar = bestOf(bestSoFar, sym);
1900137500Sjulian                }
190165543Scg            } finally {
1902137500Sjulian                env1.info.preferredTreeForDiagnostics = null;
1903137500Sjulian            }
1904137500Sjulian            if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
1905137500Sjulian            env1 = env1.outer;
190665543Scg        }
1907137500Sjulian
190865543Scg        Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
190965543Scg                                typeargtypes, allowBoxing, useVarargs);
1910174582Sariff        if (sym.exists())
1911137500Sjulian            return sym;
191265543Scg
191365543Scg        for (Symbol currentSym : env.toplevel.namedImportScope.getSymbolsByName(name)) {
191470945Sjhb            Symbol origin = env.toplevel.namedImportScope.getOrigin(currentSym).owner;
1915154067Sariff            if (currentSym.kind == MTH) {
1916137500Sjulian                if (currentSym.owner.type != origin.type)
1917154067Sariff                    currentSym = currentSym.clone(origin);
1918174582Sariff                if (!isAccessible(env, origin.type, currentSym))
1919137500Sjulian                    currentSym = new AccessError(env, origin.type, currentSym);
192070134Scg                bestSoFar = selectBest(env, origin.type,
1921137500Sjulian                                       argtypes, typeargtypes,
1922137500Sjulian                                       currentSym, bestSoFar,
1923137500Sjulian                                       allowBoxing, useVarargs);
1924137500Sjulian            }
1925137500Sjulian        }
1926137500Sjulian        if (bestSoFar.exists())
192765543Scg            return bestSoFar;
192865543Scg
192965543Scg        for (Symbol currentSym : env.toplevel.starImportScope.getSymbolsByName(name)) {
193065543Scg            Symbol origin = env.toplevel.starImportScope.getOrigin(currentSym).owner;
193165543Scg            if (currentSym.kind == MTH) {
193265644Scg                if (currentSym.owner.type != origin.type)
193365644Scg                    currentSym = currentSym.clone(origin);
193465543Scg                if (!isAccessible(env, origin.type, currentSym))
193565543Scg                    currentSym = new AccessError(env, origin.type, currentSym);
193665543Scg                bestSoFar = selectBest(env, origin.type,
193765543Scg                                       argtypes, typeargtypes,
193865543Scg                                       currentSym, bestSoFar,
193965543Scg                                       allowBoxing, useVarargs);
1940154627Snetchild            }
1941154627Snetchild        }
1942154627Snetchild        return bestSoFar;
1943154627Snetchild    }
1944154627Snetchild
1945154627Snetchild    /** Load toplevel or member class with given fully qualified name and
1946154627Snetchild     *  verify that it is accessible.
1947154627Snetchild     *  @param env       The current environment.
1948154627Snetchild     *  @param name      The fully qualified name of the class to be loaded.
194965543Scg     */
1950154627Snetchild    Symbol loadClass(Env<AttrContext> env, Name name) {
195165543Scg        try {
1952137500Sjulian            ClassSymbol c = finder.loadClass(name);
195365543Scg            return isAccessible(env, c) ? c : new AccessError(c);
195465543Scg        } catch (ClassFinder.BadClassFile err) {
195565543Scg            throw err;
195665543Scg        } catch (CompletionFailure ex) {
195765543Scg            return typeNotFound;
195865543Scg        }
195965543Scg    }
1960137500Sjulian
196165543Scg
1962137500Sjulian    /**
1963137500Sjulian     * Find a type declared in a scope (not inherited).  Return null
1964137500Sjulian     * if none is found.
1965137500Sjulian     *  @param env       The current environment.
1966137500Sjulian     *  @param site      The original type from where the selection takes
1967137500Sjulian     *                   place.
1968137500Sjulian     *  @param name      The type's name.
1969137500Sjulian     *  @param c         The class to search for the member type. This is
1970137500Sjulian     *                   always a superclass or implemented interface of
1971137500Sjulian     *                   site's class.
1972137500Sjulian     */
197365543Scg    Symbol findImmediateMemberType(Env<AttrContext> env,
1974137500Sjulian                                   Type site,
1975137500Sjulian                                   Name name,
197665543Scg                                   TypeSymbol c) {
1977137500Sjulian        for (Symbol sym : c.members().getSymbolsByName(name)) {
197865543Scg            if (sym.kind == TYP) {
1979137500Sjulian                return isAccessible(env, site, sym)
1980137500Sjulian                    ? sym
1981154067Sariff                    : new AccessError(env, site, sym);
198265543Scg            }
198365543Scg        }
198465543Scg        return typeNotFound;
198565543Scg    }
1986137500Sjulian
1987137500Sjulian    /** Find a member type inherited from a superclass or interface.
1988137500Sjulian     *  @param env       The current environment.
1989137500Sjulian     *  @param site      The original type from where the selection takes
199065543Scg     *                   place.
199165543Scg     *  @param name      The type's name.
199265543Scg     *  @param c         The class to search for the member type. This is
199365543Scg     *                   always a superclass or implemented interface of
199465543Scg     *                   site's class.
199565543Scg     */
199665543Scg    Symbol findInheritedMemberType(Env<AttrContext> env,
199765543Scg                                   Type site,
199865543Scg                                   Name name,
1999137500Sjulian                                   TypeSymbol c) {
2000137500Sjulian        Symbol bestSoFar = typeNotFound;
2001137500Sjulian        Symbol sym;
2002137500Sjulian        Type st = types.supertype(c.type);
200365543Scg        if (st != null && st.hasTag(CLASS)) {
200465543Scg            sym = findMemberType(env, site, name, st.tsym);
200565543Scg            bestSoFar = bestOf(bestSoFar, sym);
200665543Scg        }
200765543Scg        for (List<Type> l = types.interfaces(c.type);
200865543Scg             bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
200965543Scg             l = l.tail) {
2010137500Sjulian            sym = findMemberType(env, site, name, l.head.tsym);
201165543Scg            if (!bestSoFar.kind.isResolutionError() &&
201265543Scg                !sym.kind.isResolutionError() &&
201365543Scg                sym.owner != bestSoFar.owner)
201465543Scg                bestSoFar = new AmbiguityError(bestSoFar, sym);
201565543Scg            else
201665543Scg                bestSoFar = bestOf(bestSoFar, sym);
201765543Scg        }
2018137500Sjulian        return bestSoFar;
2019137500Sjulian    }
2020137500Sjulian
2021137500Sjulian    /** Find qualified member type.
2022137500Sjulian     *  @param env       The current environment.
2023137500Sjulian     *  @param site      The original type from where the selection takes
2024137500Sjulian     *                   place.
2025137500Sjulian     *  @param name      The type's name.
2026137500Sjulian     *  @param c         The class to search for the member type. This is
202765543Scg     *                   always a superclass or implemented interface of
2028137500Sjulian     *                   site's class.
202965543Scg     */
203065543Scg    Symbol findMemberType(Env<AttrContext> env,
203165543Scg                          Type site,
203265543Scg                          Name name,
203365543Scg                          TypeSymbol c) {
203465543Scg        Symbol sym = findImmediateMemberType(env, site, name, c);
203565543Scg
203665543Scg        if (sym != typeNotFound)
2037137500Sjulian            return sym;
2038137500Sjulian
2039137500Sjulian        return findInheritedMemberType(env, site, name, c);
204065543Scg
204165543Scg    }
204265543Scg
204365543Scg    /** Find a global type in given scope and load corresponding class.
204465543Scg     *  @param env       The current environment.
204565543Scg     *  @param scope     The scope in which to look for the type.
204665543Scg     *  @param name      The type's name.
204765543Scg     */
204865543Scg    Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {
204965543Scg        Symbol bestSoFar = typeNotFound;
205065543Scg        for (Symbol s : scope.getSymbolsByName(name)) {
205165543Scg            Symbol sym = loadClass(env, s.flatName());
205265543Scg            if (bestSoFar.kind == TYP && sym.kind == TYP &&
205365543Scg                bestSoFar != sym)
205465543Scg                return new AmbiguityError(bestSoFar, sym);
205565543Scg            else
205665543Scg                bestSoFar = bestOf(bestSoFar, sym);
205765543Scg        }
205865543Scg        return bestSoFar;
205982180Scg    }
206065543Scg
206165543Scg    Symbol findTypeVar(Env<AttrContext> env, Name name, boolean staticOnly) {
2062137500Sjulian        for (Symbol sym : env.info.scope.getSymbolsByName(name)) {
2063137500Sjulian            if (sym.kind == TYP) {
206465543Scg                if (staticOnly &&
2065132236Stanimura                    sym.type.hasTag(TYPEVAR) &&
206665543Scg                    sym.owner.kind == TYP)
2067                    return new StaticError(sym);
2068                return sym;
2069            }
2070        }
2071        return typeNotFound;
2072    }
2073
2074    /** Find an unqualified type symbol.
2075     *  @param env       The current environment.
2076     *  @param name      The type's name.
2077     */
2078    Symbol findType(Env<AttrContext> env, Name name) {
2079        if (name == names.empty)
2080            return typeNotFound; // do not allow inadvertent "lookup" of anonymous types
2081        Symbol bestSoFar = typeNotFound;
2082        Symbol sym;
2083        boolean staticOnly = false;
2084        for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {
2085            if (isStatic(env1)) staticOnly = true;
2086            // First, look for a type variable and the first member type
2087            final Symbol tyvar = findTypeVar(env1, name, staticOnly);
2088            sym = findImmediateMemberType(env1, env1.enclClass.sym.type,
2089                                          name, env1.enclClass.sym);
2090
2091            // Return the type variable if we have it, and have no
2092            // immediate member, OR the type variable is for a method.
2093            if (tyvar != typeNotFound) {
2094                if (env.baseClause || sym == typeNotFound ||
2095                    (tyvar.kind == TYP && tyvar.exists() &&
2096                     tyvar.owner.kind == MTH)) {
2097                    return tyvar;
2098                }
2099            }
2100
2101            // If the environment is a class def, finish up,
2102            // otherwise, do the entire findMemberType
2103            if (sym == typeNotFound)
2104                sym = findInheritedMemberType(env1, env1.enclClass.sym.type,
2105                                              name, env1.enclClass.sym);
2106
2107            if (staticOnly && sym.kind == TYP &&
2108                sym.type.hasTag(CLASS) &&
2109                sym.type.getEnclosingType().hasTag(CLASS) &&
2110                env1.enclClass.sym.type.isParameterized() &&
2111                sym.type.getEnclosingType().isParameterized())
2112                return new StaticError(sym);
2113            else if (sym.exists()) return sym;
2114            else bestSoFar = bestOf(bestSoFar, sym);
2115
2116            JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass;
2117            if ((encl.sym.flags() & STATIC) != 0)
2118                staticOnly = true;
2119        }
2120
2121        if (!env.tree.hasTag(IMPORT)) {
2122            sym = findGlobalType(env, env.toplevel.namedImportScope, name);
2123            if (sym.exists()) return sym;
2124            else bestSoFar = bestOf(bestSoFar, sym);
2125
2126            sym = findGlobalType(env, env.toplevel.packge.members(), name);
2127            if (sym.exists()) return sym;
2128            else bestSoFar = bestOf(bestSoFar, sym);
2129
2130            sym = findGlobalType(env, env.toplevel.starImportScope, name);
2131            if (sym.exists()) return sym;
2132            else bestSoFar = bestOf(bestSoFar, sym);
2133        }
2134
2135        return bestSoFar;
2136    }
2137
2138    /** Find an unqualified identifier which matches a specified kind set.
2139     *  @param env       The current environment.
2140     *  @param name      The identifier's name.
2141     *  @param kind      Indicates the possible symbol kinds
2142     *                   (a subset of VAL, TYP, PCK).
2143     */
2144    Symbol findIdent(Env<AttrContext> env, Name name, KindSelector kind) {
2145        Symbol bestSoFar = typeNotFound;
2146        Symbol sym;
2147
2148        if (kind.contains(KindSelector.VAL)) {
2149            sym = findVar(env, name);
2150            if (sym.exists()) return sym;
2151            else bestSoFar = bestOf(bestSoFar, sym);
2152        }
2153
2154        if (kind.contains(KindSelector.TYP)) {
2155            sym = findType(env, name);
2156
2157            if (sym.exists()) return sym;
2158            else bestSoFar = bestOf(bestSoFar, sym);
2159        }
2160
2161        if (kind.contains(KindSelector.PCK))
2162            return syms.enterPackage(name);
2163        else return bestSoFar;
2164    }
2165
2166    /** Find an identifier in a package which matches a specified kind set.
2167     *  @param env       The current environment.
2168     *  @param name      The identifier's name.
2169     *  @param kind      Indicates the possible symbol kinds
2170     *                   (a nonempty subset of TYP, PCK).
2171     */
2172    Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck,
2173                              Name name, KindSelector kind) {
2174        Name fullname = TypeSymbol.formFullName(name, pck);
2175        Symbol bestSoFar = typeNotFound;
2176        PackageSymbol pack = null;
2177        if (kind.contains(KindSelector.PCK)) {
2178            pack = syms.enterPackage(fullname);
2179            if (pack.exists()) return pack;
2180        }
2181        if (kind.contains(KindSelector.TYP)) {
2182            Symbol sym = loadClass(env, fullname);
2183            if (sym.exists()) {
2184                // don't allow programs to use flatnames
2185                if (name == sym.name) return sym;
2186            }
2187            else bestSoFar = bestOf(bestSoFar, sym);
2188        }
2189        return (pack != null) ? pack : bestSoFar;
2190    }
2191
2192    /** Find an identifier among the members of a given type `site'.
2193     *  @param env       The current environment.
2194     *  @param site      The type containing the symbol to be found.
2195     *  @param name      The identifier's name.
2196     *  @param kind      Indicates the possible symbol kinds
2197     *                   (a subset of VAL, TYP).
2198     */
2199    Symbol findIdentInType(Env<AttrContext> env, Type site,
2200                           Name name, KindSelector kind) {
2201        Symbol bestSoFar = typeNotFound;
2202        Symbol sym;
2203        if (kind.contains(KindSelector.VAL)) {
2204            sym = findField(env, site, name, site.tsym);
2205            if (sym.exists()) return sym;
2206            else bestSoFar = bestOf(bestSoFar, sym);
2207        }
2208
2209        if (kind.contains(KindSelector.TYP)) {
2210            sym = findMemberType(env, site, name, site.tsym);
2211            if (sym.exists()) return sym;
2212            else bestSoFar = bestOf(bestSoFar, sym);
2213        }
2214        return bestSoFar;
2215    }
2216
2217/* ***************************************************************************
2218 *  Access checking
2219 *  The following methods convert ResolveErrors to ErrorSymbols, issuing
2220 *  an error message in the process
2221 ****************************************************************************/
2222
2223    /** If `sym' is a bad symbol: report error and return errSymbol
2224     *  else pass through unchanged,
2225     *  additional arguments duplicate what has been used in trying to find the
2226     *  symbol {@literal (--> flyweight pattern)}. This improves performance since we
2227     *  expect misses to happen frequently.
2228     *
2229     *  @param sym       The symbol that was found, or a ResolveError.
2230     *  @param pos       The position to use for error reporting.
2231     *  @param location  The symbol the served as a context for this lookup
2232     *  @param site      The original type from where the selection took place.
2233     *  @param name      The symbol's name.
2234     *  @param qualified Did we get here through a qualified expression resolution?
2235     *  @param argtypes  The invocation's value arguments,
2236     *                   if we looked for a method.
2237     *  @param typeargtypes  The invocation's type arguments,
2238     *                   if we looked for a method.
2239     *  @param logResolveHelper helper class used to log resolve errors
2240     */
2241    Symbol accessInternal(Symbol sym,
2242                  DiagnosticPosition pos,
2243                  Symbol location,
2244                  Type site,
2245                  Name name,
2246                  boolean qualified,
2247                  List<Type> argtypes,
2248                  List<Type> typeargtypes,
2249                  LogResolveHelper logResolveHelper) {
2250        if (sym.kind.isResolutionError()) {
2251            ResolveError errSym = (ResolveError)sym.baseSymbol();
2252            sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol);
2253            argtypes = logResolveHelper.getArgumentTypes(errSym, sym, name, argtypes);
2254            if (logResolveHelper.resolveDiagnosticNeeded(site, argtypes, typeargtypes)) {
2255                logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes);
2256            }
2257        }
2258        return sym;
2259    }
2260
2261    /**
2262     * Variant of the generalized access routine, to be used for generating method
2263     * resolution diagnostics
2264     */
2265    Symbol accessMethod(Symbol sym,
2266                  DiagnosticPosition pos,
2267                  Symbol location,
2268                  Type site,
2269                  Name name,
2270                  boolean qualified,
2271                  List<Type> argtypes,
2272                  List<Type> typeargtypes) {
2273        return accessInternal(sym, pos, location, site, name, qualified, argtypes, typeargtypes, methodLogResolveHelper);
2274    }
2275
2276    /** Same as original accessMethod(), but without location.
2277     */
2278    Symbol accessMethod(Symbol sym,
2279                  DiagnosticPosition pos,
2280                  Type site,
2281                  Name name,
2282                  boolean qualified,
2283                  List<Type> argtypes,
2284                  List<Type> typeargtypes) {
2285        return accessMethod(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes);
2286    }
2287
2288    /**
2289     * Variant of the generalized access routine, to be used for generating variable,
2290     * type resolution diagnostics
2291     */
2292    Symbol accessBase(Symbol sym,
2293                  DiagnosticPosition pos,
2294                  Symbol location,
2295                  Type site,
2296                  Name name,
2297                  boolean qualified) {
2298        return accessInternal(sym, pos, location, site, name, qualified, List.<Type>nil(), null, basicLogResolveHelper);
2299    }
2300
2301    /** Same as original accessBase(), but without location.
2302     */
2303    Symbol accessBase(Symbol sym,
2304                  DiagnosticPosition pos,
2305                  Type site,
2306                  Name name,
2307                  boolean qualified) {
2308        return accessBase(sym, pos, site.tsym, site, name, qualified);
2309    }
2310
2311    interface LogResolveHelper {
2312        boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes);
2313        List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes);
2314    }
2315
2316    LogResolveHelper basicLogResolveHelper = new LogResolveHelper() {
2317        public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2318            return !site.isErroneous();
2319        }
2320        public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2321            return argtypes;
2322        }
2323    };
2324
2325    LogResolveHelper methodLogResolveHelper = new LogResolveHelper() {
2326        public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2327            return !site.isErroneous() &&
2328                        !Type.isErroneous(argtypes) &&
2329                        (typeargtypes == null || !Type.isErroneous(typeargtypes));
2330        }
2331        public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2332            return argtypes.map(new ResolveDeferredRecoveryMap(AttrMode.SPECULATIVE, accessedSym, currentResolutionContext.step));
2333        }
2334    };
2335
2336    class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap {
2337
2338        public ResolveDeferredRecoveryMap(AttrMode mode, Symbol msym, MethodResolutionPhase step) {
2339            deferredAttr.super(mode, msym, step);
2340        }
2341
2342        @Override
2343        protected Type typeOf(DeferredType dt) {
2344            Type res = super.typeOf(dt);
2345            if (!res.isErroneous()) {
2346                switch (TreeInfo.skipParens(dt.tree).getTag()) {
2347                    case LAMBDA:
2348                    case REFERENCE:
2349                        return dt;
2350                    case CONDEXPR:
2351                        return res == Type.recoveryType ?
2352                                dt : res;
2353                }
2354            }
2355            return res;
2356        }
2357    }
2358
2359    /** Check that sym is not an abstract method.
2360     */
2361    void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
2362        if ((sym.flags() & ABSTRACT) != 0 && (sym.flags() & DEFAULT) == 0)
2363            log.error(pos, "abstract.cant.be.accessed.directly",
2364                      kindName(sym), sym, sym.location());
2365    }
2366
2367/* ***************************************************************************
2368 *  Name resolution
2369 *  Naming conventions are as for symbol lookup
2370 *  Unlike the find... methods these methods will report access errors
2371 ****************************************************************************/
2372
2373    /** Resolve an unqualified (non-method) identifier.
2374     *  @param pos       The position to use for error reporting.
2375     *  @param env       The environment current at the identifier use.
2376     *  @param name      The identifier's name.
2377     *  @param kind      The set of admissible symbol kinds for the identifier.
2378     */
2379    Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,
2380                        Name name, KindSelector kind) {
2381        return accessBase(
2382            findIdent(env, name, kind),
2383            pos, env.enclClass.sym.type, name, false);
2384    }
2385
2386    /** Resolve an unqualified method identifier.
2387     *  @param pos       The position to use for error reporting.
2388     *  @param env       The environment current at the method invocation.
2389     *  @param name      The identifier's name.
2390     *  @param argtypes  The types of the invocation's value arguments.
2391     *  @param typeargtypes  The types of the invocation's type arguments.
2392     */
2393    Symbol resolveMethod(DiagnosticPosition pos,
2394                         Env<AttrContext> env,
2395                         Name name,
2396                         List<Type> argtypes,
2397                         List<Type> typeargtypes) {
2398        return lookupMethod(env, pos, env.enclClass.sym, resolveMethodCheck,
2399                new BasicLookupHelper(name, env.enclClass.sym.type, argtypes, typeargtypes) {
2400                    @Override
2401                    Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2402                        return findFun(env, name, argtypes, typeargtypes,
2403                                phase.isBoxingRequired(),
2404                                phase.isVarargsRequired());
2405                    }});
2406    }
2407
2408    /** Resolve a qualified method identifier
2409     *  @param pos       The position to use for error reporting.
2410     *  @param env       The environment current at the method invocation.
2411     *  @param site      The type of the qualifying expression, in which
2412     *                   identifier is searched.
2413     *  @param name      The identifier's name.
2414     *  @param argtypes  The types of the invocation's value arguments.
2415     *  @param typeargtypes  The types of the invocation's type arguments.
2416     */
2417    Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
2418                                  Type site, Name name, List<Type> argtypes,
2419                                  List<Type> typeargtypes) {
2420        return resolveQualifiedMethod(pos, env, site.tsym, site, name, argtypes, typeargtypes);
2421    }
2422    Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
2423                                  Symbol location, Type site, Name name, List<Type> argtypes,
2424                                  List<Type> typeargtypes) {
2425        return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes);
2426    }
2427    private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext,
2428                                  DiagnosticPosition pos, Env<AttrContext> env,
2429                                  Symbol location, Type site, Name name, List<Type> argtypes,
2430                                  List<Type> typeargtypes) {
2431        return lookupMethod(env, pos, location, resolveContext, new BasicLookupHelper(name, site, argtypes, typeargtypes) {
2432            @Override
2433            Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2434                return findMethod(env, site, name, argtypes, typeargtypes,
2435                        phase.isBoxingRequired(),
2436                        phase.isVarargsRequired());
2437            }
2438            @Override
2439            Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2440                if (sym.kind.isResolutionError()) {
2441                    sym = super.access(env, pos, location, sym);
2442                } else if (allowMethodHandles) {
2443                    MethodSymbol msym = (MethodSymbol)sym;
2444                    if ((msym.flags() & SIGNATURE_POLYMORPHIC) != 0) {
2445                        return findPolymorphicSignatureInstance(env, sym, argtypes);
2446                    }
2447                }
2448                return sym;
2449            }
2450        });
2451    }
2452
2453    /** Find or create an implicit method of exactly the given type (after erasure).
2454     *  Searches in a side table, not the main scope of the site.
2455     *  This emulates the lookup process required by JSR 292 in JVM.
2456     *  @param env       Attribution environment
2457     *  @param spMethod  signature polymorphic method - i.e. MH.invokeExact
2458     *  @param argtypes  The required argument types
2459     */
2460    Symbol findPolymorphicSignatureInstance(Env<AttrContext> env,
2461                                            final Symbol spMethod,
2462                                            List<Type> argtypes) {
2463        Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
2464                (MethodSymbol)spMethod, currentResolutionContext, argtypes);
2465        for (Symbol sym : polymorphicSignatureScope.getSymbolsByName(spMethod.name)) {
2466            if (types.isSameType(mtype, sym.type)) {
2467               return sym;
2468            }
2469        }
2470
2471        // create the desired method
2472        long flags = ABSTRACT | HYPOTHETICAL | spMethod.flags() & Flags.AccessFlags;
2473        Symbol msym = new MethodSymbol(flags, spMethod.name, mtype, spMethod.owner) {
2474            @Override
2475            public Symbol baseSymbol() {
2476                return spMethod;
2477            }
2478        };
2479        if (!mtype.isErroneous()) { // Cache only if kosher.
2480            polymorphicSignatureScope.enter(msym);
2481        }
2482        return msym;
2483    }
2484
2485    /** Resolve a qualified method identifier, throw a fatal error if not
2486     *  found.
2487     *  @param pos       The position to use for error reporting.
2488     *  @param env       The environment current at the method invocation.
2489     *  @param site      The type of the qualifying expression, in which
2490     *                   identifier is searched.
2491     *  @param name      The identifier's name.
2492     *  @param argtypes  The types of the invocation's value arguments.
2493     *  @param typeargtypes  The types of the invocation's type arguments.
2494     */
2495    public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env,
2496                                        Type site, Name name,
2497                                        List<Type> argtypes,
2498                                        List<Type> typeargtypes) {
2499        MethodResolutionContext resolveContext = new MethodResolutionContext();
2500        resolveContext.internalResolution = true;
2501        Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym,
2502                site, name, argtypes, typeargtypes);
2503        if (sym.kind == MTH) return (MethodSymbol)sym;
2504        else throw new FatalError(
2505                 diags.fragment("fatal.err.cant.locate.meth",
2506                                name));
2507    }
2508
2509    /** Resolve constructor.
2510     *  @param pos       The position to use for error reporting.
2511     *  @param env       The environment current at the constructor invocation.
2512     *  @param site      The type of class for which a constructor is searched.
2513     *  @param argtypes  The types of the constructor invocation's value
2514     *                   arguments.
2515     *  @param typeargtypes  The types of the constructor invocation's type
2516     *                   arguments.
2517     */
2518    Symbol resolveConstructor(DiagnosticPosition pos,
2519                              Env<AttrContext> env,
2520                              Type site,
2521                              List<Type> argtypes,
2522                              List<Type> typeargtypes) {
2523        return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes);
2524    }
2525
2526    private Symbol resolveConstructor(MethodResolutionContext resolveContext,
2527                              final DiagnosticPosition pos,
2528                              Env<AttrContext> env,
2529                              Type site,
2530                              List<Type> argtypes,
2531                              List<Type> typeargtypes) {
2532        return lookupMethod(env, pos, site.tsym, resolveContext, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2533            @Override
2534            Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2535                return findConstructor(pos, env, site, argtypes, typeargtypes,
2536                        phase.isBoxingRequired(),
2537                        phase.isVarargsRequired());
2538            }
2539        });
2540    }
2541
2542    /** Resolve a constructor, throw a fatal error if not found.
2543     *  @param pos       The position to use for error reporting.
2544     *  @param env       The environment current at the method invocation.
2545     *  @param site      The type to be constructed.
2546     *  @param argtypes  The types of the invocation's value arguments.
2547     *  @param typeargtypes  The types of the invocation's type arguments.
2548     */
2549    public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2550                                        Type site,
2551                                        List<Type> argtypes,
2552                                        List<Type> typeargtypes) {
2553        MethodResolutionContext resolveContext = new MethodResolutionContext();
2554        resolveContext.internalResolution = true;
2555        Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
2556        if (sym.kind == MTH) return (MethodSymbol)sym;
2557        else throw new FatalError(
2558                 diags.fragment("fatal.err.cant.locate.ctor", site));
2559    }
2560
2561    Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2562                              Type site, List<Type> argtypes,
2563                              List<Type> typeargtypes,
2564                              boolean allowBoxing,
2565                              boolean useVarargs) {
2566        Symbol sym = findMethod(env, site,
2567                                    names.init, argtypes,
2568                                    typeargtypes, allowBoxing,
2569                                    useVarargs);
2570        chk.checkDeprecated(pos, env.info.scope.owner, sym);
2571        return sym;
2572    }
2573
2574    /** Resolve constructor using diamond inference.
2575     *  @param pos       The position to use for error reporting.
2576     *  @param env       The environment current at the constructor invocation.
2577     *  @param site      The type of class for which a constructor is searched.
2578     *                   The scope of this class has been touched in attribution.
2579     *  @param argtypes  The types of the constructor invocation's value
2580     *                   arguments.
2581     *  @param typeargtypes  The types of the constructor invocation's type
2582     *                   arguments.
2583     */
2584    Symbol resolveDiamond(DiagnosticPosition pos,
2585                              Env<AttrContext> env,
2586                              Type site,
2587                              List<Type> argtypes,
2588                              List<Type> typeargtypes) {
2589        return lookupMethod(env, pos, site.tsym, resolveMethodCheck,
2590                new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2591                    @Override
2592                    Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2593                        return findDiamond(env, site, argtypes, typeargtypes,
2594                                phase.isBoxingRequired(),
2595                                phase.isVarargsRequired());
2596                    }
2597                    @Override
2598                    Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2599                        if (sym.kind.isResolutionError()) {
2600                            if (sym.kind != WRONG_MTH &&
2601                                sym.kind != WRONG_MTHS) {
2602                                sym = super.access(env, pos, location, sym);
2603                            } else {
2604                                final JCDiagnostic details = sym.kind == WRONG_MTH ?
2605                                                ((InapplicableSymbolError)sym.baseSymbol()).errCandidate().snd :
2606                                                null;
2607                                sym = new DiamondError(sym, currentResolutionContext);
2608                                sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
2609                                env.info.pendingResolutionPhase = currentResolutionContext.step;
2610                            }
2611                        }
2612                        return sym;
2613                    }});
2614    }
2615
2616    /** This method scans all the constructor symbol in a given class scope -
2617     *  assuming that the original scope contains a constructor of the kind:
2618     *  {@code Foo(X x, Y y)}, where X,Y are class type-variables declared in Foo,
2619     *  a method check is executed against the modified constructor type:
2620     *  {@code <X,Y>Foo<X,Y>(X x, Y y)}. This is crucial in order to enable diamond
2621     *  inference. The inferred return type of the synthetic constructor IS
2622     *  the inferred type for the diamond operator.
2623     */
2624    private Symbol findDiamond(Env<AttrContext> env,
2625                              Type site,
2626                              List<Type> argtypes,
2627                              List<Type> typeargtypes,
2628                              boolean allowBoxing,
2629                              boolean useVarargs) {
2630        Symbol bestSoFar = methodNotFound;
2631        TypeSymbol tsym = site.tsym.isInterface() ? syms.objectType.tsym : site.tsym;
2632        for (final Symbol sym : tsym.members().getSymbolsByName(names.init)) {
2633            //- System.out.println(" e " + e.sym);
2634            if (sym.kind == MTH &&
2635                (sym.flags_field & SYNTHETIC) == 0) {
2636                    List<Type> oldParams = sym.type.hasTag(FORALL) ?
2637                            ((ForAll)sym.type).tvars :
2638                            List.<Type>nil();
2639                    Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
2640                                                 types.createMethodTypeWithReturn(sym.type.asMethodType(), site));
2641                    MethodSymbol newConstr = new MethodSymbol(sym.flags(), names.init, constrType, site.tsym) {
2642                        @Override
2643                        public Symbol baseSymbol() {
2644                            return sym;
2645                        }
2646                    };
2647                    bestSoFar = selectBest(env, site, argtypes, typeargtypes,
2648                            newConstr,
2649                            bestSoFar,
2650                            allowBoxing,
2651                            useVarargs);
2652            }
2653        }
2654        return bestSoFar;
2655    }
2656
2657    Symbol getMemberReference(DiagnosticPosition pos,
2658            Env<AttrContext> env,
2659            JCMemberReference referenceTree,
2660            Type site,
2661            Name name) {
2662
2663        site = types.capture(site);
2664
2665        ReferenceLookupHelper lookupHelper = makeReferenceLookupHelper(
2666                referenceTree, site, name, List.<Type>nil(), null, VARARITY);
2667
2668        Env<AttrContext> newEnv = env.dup(env.tree, env.info.dup());
2669        Symbol sym = lookupMethod(newEnv, env.tree.pos(), site.tsym,
2670                nilMethodCheck, lookupHelper);
2671
2672        env.info.pendingResolutionPhase = newEnv.info.pendingResolutionPhase;
2673
2674        return sym;
2675    }
2676
2677    ReferenceLookupHelper makeReferenceLookupHelper(JCMemberReference referenceTree,
2678                                  Type site,
2679                                  Name name,
2680                                  List<Type> argtypes,
2681                                  List<Type> typeargtypes,
2682                                  MethodResolutionPhase maxPhase) {
2683        if (!name.equals(names.init)) {
2684            //method reference
2685            return new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
2686        } else if (site.hasTag(ARRAY)) {
2687            //array constructor reference
2688            return new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
2689        } else {
2690            //class constructor reference
2691            return new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
2692        }
2693    }
2694
2695    /**
2696     * Resolution of member references is typically done as a single
2697     * overload resolution step, where the argument types A are inferred from
2698     * the target functional descriptor.
2699     *
2700     * If the member reference is a method reference with a type qualifier,
2701     * a two-step lookup process is performed. The first step uses the
2702     * expected argument list A, while the second step discards the first
2703     * type from A (which is treated as a receiver type).
2704     *
2705     * There are two cases in which inference is performed: (i) if the member
2706     * reference is a constructor reference and the qualifier type is raw - in
2707     * which case diamond inference is used to infer a parameterization for the
2708     * type qualifier; (ii) if the member reference is an unbound reference
2709     * where the type qualifier is raw - in that case, during the unbound lookup
2710     * the receiver argument type is used to infer an instantiation for the raw
2711     * qualifier type.
2712     *
2713     * When a multi-step resolution process is exploited, the process of picking
2714     * the resulting symbol is delegated to an helper class {@link com.sun.tools.javac.comp.Resolve.ReferenceChooser}.
2715     *
2716     * This routine returns a pair (T,S), where S is the member reference symbol,
2717     * and T is the type of the class in which S is defined. This is necessary as
2718     * the type T might be dynamically inferred (i.e. if constructor reference
2719     * has a raw qualifier).
2720     */
2721    Pair<Symbol, ReferenceLookupHelper> resolveMemberReference(Env<AttrContext> env,
2722                                  JCMemberReference referenceTree,
2723                                  Type site,
2724                                  Name name,
2725                                  List<Type> argtypes,
2726                                  List<Type> typeargtypes,
2727                                  MethodCheck methodCheck,
2728                                  InferenceContext inferenceContext,
2729                                  ReferenceChooser referenceChooser) {
2730
2731        //step 1 - bound lookup
2732        ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper(
2733                referenceTree, site, name, argtypes, typeargtypes, VARARITY);
2734        Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
2735        MethodResolutionContext boundSearchResolveContext = new MethodResolutionContext();
2736        boundSearchResolveContext.methodCheck = methodCheck;
2737        Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(),
2738                site.tsym, boundSearchResolveContext, boundLookupHelper);
2739        ReferenceLookupResult boundRes = new ReferenceLookupResult(boundSym, boundSearchResolveContext);
2740
2741        //step 2 - unbound lookup
2742        Symbol unboundSym = methodNotFound;
2743        Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
2744        ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext);
2745        ReferenceLookupResult unboundRes = referenceNotFound;
2746        if (unboundLookupHelper != null) {
2747            MethodResolutionContext unboundSearchResolveContext =
2748                    new MethodResolutionContext();
2749            unboundSearchResolveContext.methodCheck = methodCheck;
2750            unboundSym = lookupMethod(unboundEnv, env.tree.pos(),
2751                    site.tsym, unboundSearchResolveContext, unboundLookupHelper);
2752            unboundRes = new ReferenceLookupResult(unboundSym, unboundSearchResolveContext);
2753        }
2754
2755        //merge results
2756        Pair<Symbol, ReferenceLookupHelper> res;
2757        Symbol bestSym = referenceChooser.result(boundRes, unboundRes);
2758        res = new Pair<>(bestSym,
2759                bestSym == unboundSym ? unboundLookupHelper : boundLookupHelper);
2760        env.info.pendingResolutionPhase = bestSym == unboundSym ?
2761                unboundEnv.info.pendingResolutionPhase :
2762                boundEnv.info.pendingResolutionPhase;
2763
2764        return res;
2765    }
2766
2767    /**
2768     * This class is used to represent a method reference lookup result. It keeps track of two
2769     * things: (i) the symbol found during a method reference lookup and (ii) the static kind
2770     * of the lookup (see {@link com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind}).
2771     */
2772    static class ReferenceLookupResult {
2773
2774        /**
2775         * Static kind associated with a method reference lookup. Erroneous lookups end up with
2776         * the UNDEFINED kind; successful lookups will end up with either STATIC, NON_STATIC,
2777         * depending on whether all applicable candidates are static or non-static methods,
2778         * respectively. If a successful lookup has both static and non-static applicable methods,
2779         * its kind is set to BOTH.
2780         */
2781        enum StaticKind {
2782            STATIC,
2783            NON_STATIC,
2784            BOTH,
2785            UNDEFINED;
2786
2787            /**
2788             * Retrieve the static kind associated with a given (method) symbol.
2789             */
2790            static StaticKind from(Symbol s) {
2791                return s.isStatic() ?
2792                        STATIC : NON_STATIC;
2793            }
2794
2795            /**
2796             * Merge two static kinds together.
2797             */
2798            static StaticKind reduce(StaticKind sk1, StaticKind sk2) {
2799                if (sk1 == UNDEFINED) {
2800                    return sk2;
2801                } else if (sk2 == UNDEFINED) {
2802                    return sk1;
2803                } else {
2804                    return sk1 == sk2 ? sk1 : BOTH;
2805                }
2806            }
2807        }
2808
2809        /** The static kind. */
2810        StaticKind staticKind;
2811
2812        /** The lookup result. */
2813        Symbol sym;
2814
2815        ReferenceLookupResult(Symbol sym, MethodResolutionContext resolutionContext) {
2816            this.staticKind = staticKind(sym, resolutionContext);
2817            this.sym = sym;
2818        }
2819
2820        private StaticKind staticKind(Symbol sym, MethodResolutionContext resolutionContext) {
2821            switch (sym.kind) {
2822                case MTH:
2823                case AMBIGUOUS:
2824                    return resolutionContext.candidates.stream()
2825                            .filter(c -> c.isApplicable() && c.step == resolutionContext.step)
2826                            .map(c -> StaticKind.from(c.sym))
2827                            .reduce(StaticKind::reduce)
2828                            .orElse(StaticKind.UNDEFINED);
2829                default:
2830                    return StaticKind.UNDEFINED;
2831            }
2832        }
2833
2834        /**
2835         * Does this result corresponds to a successful lookup (i.e. one where a method has been found?)
2836         */
2837        boolean isSuccess() {
2838            return staticKind != StaticKind.UNDEFINED;
2839        }
2840
2841        /**
2842         * Does this result have given static kind?
2843         */
2844        boolean hasKind(StaticKind sk) {
2845            return this.staticKind == sk;
2846        }
2847
2848        /**
2849         * Error recovery helper: can this lookup result be ignored (for the purpose of returning
2850         * some 'better' result) ?
2851         */
2852        boolean canIgnore() {
2853            switch (sym.kind) {
2854                case ABSENT_MTH:
2855                    return true;
2856                case WRONG_MTH:
2857                    InapplicableSymbolError errSym =
2858                            (InapplicableSymbolError)sym.baseSymbol();
2859                    return new Template(MethodCheckDiag.ARITY_MISMATCH.regex())
2860                            .matches(errSym.errCandidate().snd);
2861                case WRONG_MTHS:
2862                    InapplicableSymbolsError errSyms =
2863                            (InapplicableSymbolsError)sym.baseSymbol();
2864                    return errSyms.filterCandidates(errSyms.mapCandidates()).isEmpty();
2865                default:
2866                    return false;
2867            }
2868        }
2869    }
2870
2871    /**
2872     * This abstract class embodies the logic that converts one (bound lookup) or two (unbound lookup)
2873     * {@code ReferenceLookupResult} objects into a (@code Symbol), which is then regarded as the
2874     * result of method reference resolution.
2875     */
2876    abstract class ReferenceChooser {
2877        /**
2878         * Generate a result from a pair of lookup result objects. This method delegates to the
2879         * appropriate result generation routine.
2880         */
2881        Symbol result(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
2882            return unboundRes != referenceNotFound ?
2883                    unboundResult(boundRes, unboundRes) :
2884                    boundResult(boundRes);
2885        }
2886
2887        /**
2888         * Generate a symbol from a given bound lookup result.
2889         */
2890        abstract Symbol boundResult(ReferenceLookupResult boundRes);
2891
2892        /**
2893         * Generate a symbol from a pair of bound/unbound lookup results.
2894         */
2895        abstract Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes);
2896    }
2897
2898    /**
2899     * This chooser implements the selection strategy used during a full lookup; this logic
2900     * is described in JLS SE 8 (15.3.2).
2901     */
2902    ReferenceChooser basicReferenceChooser = new ReferenceChooser() {
2903
2904        @Override
2905        Symbol boundResult(ReferenceLookupResult boundRes) {
2906            return !boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC) ?
2907                    boundRes.sym : //the search produces a non-static method
2908                    new BadMethodReferenceError(boundRes.sym, false);
2909        }
2910
2911        @Override
2912        Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
2913            if (boundRes.hasKind(StaticKind.STATIC) &&
2914                    (!unboundRes.isSuccess() || unboundRes.hasKind(StaticKind.STATIC))) {
2915                //the first search produces a static method and no non-static method is applicable
2916                //during the second search
2917                return boundRes.sym;
2918            } else if (unboundRes.hasKind(StaticKind.NON_STATIC) &&
2919                    (!boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC))) {
2920                //the second search produces a non-static method and no static method is applicable
2921                //during the first search
2922                return unboundRes.sym;
2923            } else if (boundRes.isSuccess() && unboundRes.isSuccess()) {
2924                //both searches produce some result; ambiguity (error recovery)
2925                return ambiguityError(boundRes.sym, unboundRes.sym);
2926            } else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
2927                //Both searches failed to produce a result with correct staticness (i.e. first search
2928                //produces an non-static method). Alternatively, a given search produced a result
2929                //with the right staticness, but the other search has applicable methods with wrong
2930                //staticness (error recovery)
2931                return new BadMethodReferenceError(boundRes.isSuccess() ? boundRes.sym : unboundRes.sym, true);
2932            } else {
2933                //both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
2934                return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
2935                        unboundRes.sym : boundRes.sym;
2936            }
2937        }
2938    };
2939
2940    /**
2941     * This chooser implements the selection strategy used during an arity-based lookup; this logic
2942     * is described in JLS SE 8 (15.12.2.1).
2943     */
2944    ReferenceChooser structuralReferenceChooser = new ReferenceChooser() {
2945
2946        @Override
2947        Symbol boundResult(ReferenceLookupResult boundRes) {
2948            return (!boundRes.isSuccess() || !boundRes.hasKind(StaticKind.STATIC)) ?
2949                    boundRes.sym : //the search has at least one applicable non-static method
2950                    new BadMethodReferenceError(boundRes.sym, false);
2951        }
2952
2953        @Override
2954        Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
2955            if (boundRes.isSuccess() && !boundRes.hasKind(StaticKind.NON_STATIC)) {
2956                //the first serach has at least one applicable static method
2957                return boundRes.sym;
2958            } else if (unboundRes.isSuccess() && !unboundRes.hasKind(StaticKind.STATIC)) {
2959                //the second search has at least one applicable non-static method
2960                return unboundRes.sym;
2961            } else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
2962                //either the first search produces a non-static method, or second search produces
2963                //a non-static method (error recovery)
2964                return new BadMethodReferenceError(boundRes.isSuccess() ? boundRes.sym : unboundRes.sym, true);
2965            } else {
2966                //both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
2967                return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
2968                        unboundRes.sym : boundRes.sym;
2969            }
2970        }
2971    };
2972
2973    /**
2974     * Helper for defining custom method-like lookup logic; a lookup helper
2975     * provides hooks for (i) the actual lookup logic and (ii) accessing the
2976     * lookup result (this step might result in compiler diagnostics to be generated)
2977     */
2978    abstract class LookupHelper {
2979
2980        /** name of the symbol to lookup */
2981        Name name;
2982
2983        /** location in which the lookup takes place */
2984        Type site;
2985
2986        /** actual types used during the lookup */
2987        List<Type> argtypes;
2988
2989        /** type arguments used during the lookup */
2990        List<Type> typeargtypes;
2991
2992        /** Max overload resolution phase handled by this helper */
2993        MethodResolutionPhase maxPhase;
2994
2995        LookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2996            this.name = name;
2997            this.site = site;
2998            this.argtypes = argtypes;
2999            this.typeargtypes = typeargtypes;
3000            this.maxPhase = maxPhase;
3001        }
3002
3003        /**
3004         * Should lookup stop at given phase with given result
3005         */
3006        final boolean shouldStop(Symbol sym, MethodResolutionPhase phase) {
3007            return phase.ordinal() > maxPhase.ordinal() ||
3008                !sym.kind.isResolutionError() || sym.kind == AMBIGUOUS;
3009        }
3010
3011        /**
3012         * Search for a symbol under a given overload resolution phase - this method
3013         * is usually called several times, once per each overload resolution phase
3014         */
3015        abstract Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase);
3016
3017        /**
3018         * Dump overload resolution info
3019         */
3020        void debug(DiagnosticPosition pos, Symbol sym) {
3021            //do nothing
3022        }
3023
3024        /**
3025         * Validate the result of the lookup
3026         */
3027        abstract Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym);
3028    }
3029
3030    abstract class BasicLookupHelper extends LookupHelper {
3031
3032        BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) {
3033            this(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY);
3034        }
3035
3036        BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3037            super(name, site, argtypes, typeargtypes, maxPhase);
3038        }
3039
3040        @Override
3041        final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3042            Symbol sym = doLookup(env, phase);
3043            if (sym.kind == AMBIGUOUS) {
3044                AmbiguityError a_err = (AmbiguityError)sym.baseSymbol();
3045                sym = a_err.mergeAbstracts(site);
3046            }
3047            return sym;
3048        }
3049
3050        abstract Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase);
3051
3052        @Override
3053        Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3054            if (sym.kind.isResolutionError()) {
3055                //if nothing is found return the 'first' error
3056                sym = accessMethod(sym, pos, location, site, name, true, argtypes, typeargtypes);
3057            }
3058            return sym;
3059        }
3060
3061        @Override
3062        void debug(DiagnosticPosition pos, Symbol sym) {
3063            reportVerboseResolutionDiagnostic(pos, name, site, argtypes, typeargtypes, sym);
3064        }
3065    }
3066
3067    /**
3068     * Helper class for member reference lookup. A reference lookup helper
3069     * defines the basic logic for member reference lookup; a method gives
3070     * access to an 'unbound' helper used to perform an unbound member
3071     * reference lookup.
3072     */
3073    abstract class ReferenceLookupHelper extends LookupHelper {
3074
3075        /** The member reference tree */
3076        JCMemberReference referenceTree;
3077
3078        ReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3079                List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3080            super(name, site, argtypes, typeargtypes, maxPhase);
3081            this.referenceTree = referenceTree;
3082        }
3083
3084        /**
3085         * Returns an unbound version of this lookup helper. By default, this
3086         * method returns an dummy lookup helper.
3087         */
3088        ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3089            return null;
3090        }
3091
3092        /**
3093         * Get the kind of the member reference
3094         */
3095        abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym);
3096
3097        Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3098            if (sym.kind == AMBIGUOUS) {
3099                AmbiguityError a_err = (AmbiguityError)sym.baseSymbol();
3100                sym = a_err.mergeAbstracts(site);
3101            }
3102            //skip error reporting
3103            return sym;
3104        }
3105    }
3106
3107    /**
3108     * Helper class for method reference lookup. The lookup logic is based
3109     * upon Resolve.findMethod; in certain cases, this helper class has a
3110     * corresponding unbound helper class (see UnboundMethodReferenceLookupHelper).
3111     * In such cases, non-static lookup results are thrown away.
3112     */
3113    class MethodReferenceLookupHelper extends ReferenceLookupHelper {
3114
3115        /** The original method reference lookup site. */
3116        Type originalSite;
3117
3118        MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3119                List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3120            super(referenceTree, name, types.skipTypeVars(site, true), argtypes, typeargtypes, maxPhase);
3121            this.originalSite = site;
3122        }
3123
3124        @Override
3125        final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3126            return findMethod(env, site, name, argtypes, typeargtypes,
3127                    phase.isBoxingRequired(), phase.isVarargsRequired());
3128        }
3129
3130        @Override
3131        ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3132            if (TreeInfo.isStaticSelector(referenceTree.expr, names)) {
3133                if (argtypes.nonEmpty() &&
3134                        (argtypes.head.hasTag(NONE) ||
3135                        types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), site))) {
3136                    return new UnboundMethodReferenceLookupHelper(referenceTree, name,
3137                            originalSite, argtypes, typeargtypes, maxPhase);
3138                } else {
3139                    return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
3140                        @Override
3141                        ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3142                            return this;
3143                        }
3144
3145                        @Override
3146                        Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3147                            return methodNotFound;
3148                        }
3149
3150                        @Override
3151                        ReferenceKind referenceKind(Symbol sym) {
3152                            Assert.error();
3153                            return null;
3154                        }
3155                    };
3156                }
3157            } else {
3158                return super.unboundLookup(inferenceContext);
3159            }
3160        }
3161
3162        @Override
3163        ReferenceKind referenceKind(Symbol sym) {
3164            if (sym.isStatic()) {
3165                return ReferenceKind.STATIC;
3166            } else {
3167                Name selName = TreeInfo.name(referenceTree.getQualifierExpression());
3168                return selName != null && selName == names._super ?
3169                        ReferenceKind.SUPER :
3170                        ReferenceKind.BOUND;
3171            }
3172        }
3173    }
3174
3175    /**
3176     * Helper class for unbound method reference lookup. Essentially the same
3177     * as the basic method reference lookup helper; main difference is that static
3178     * lookup results are thrown away. If qualifier type is raw, an attempt to
3179     * infer a parameterized type is made using the first actual argument (that
3180     * would otherwise be ignored during the lookup).
3181     */
3182    class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper {
3183
3184        UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3185                List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3186            super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase);
3187            if (site.isRaw() && !argtypes.head.hasTag(NONE)) {
3188                Type asSuperSite = types.asSuper(argtypes.head, site.tsym);
3189                this.site = types.skipTypeVars(asSuperSite, true);
3190            }
3191        }
3192
3193        @Override
3194        ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3195            return this;
3196        }
3197
3198        @Override
3199        ReferenceKind referenceKind(Symbol sym) {
3200            return ReferenceKind.UNBOUND;
3201        }
3202    }
3203
3204    /**
3205     * Helper class for array constructor lookup; an array constructor lookup
3206     * is simulated by looking up a method that returns the array type specified
3207     * as qualifier, and that accepts a single int parameter (size of the array).
3208     */
3209    class ArrayConstructorReferenceLookupHelper extends ReferenceLookupHelper {
3210
3211        ArrayConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
3212                List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3213            super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
3214        }
3215
3216        @Override
3217        protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3218            WriteableScope sc = WriteableScope.create(syms.arrayClass);
3219            MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym);
3220            arrayConstr.type = new MethodType(List.<Type>of(syms.intType), site, List.<Type>nil(), syms.methodClass);
3221            sc.enter(arrayConstr);
3222            return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false);
3223        }
3224
3225        @Override
3226        ReferenceKind referenceKind(Symbol sym) {
3227            return ReferenceKind.ARRAY_CTOR;
3228        }
3229    }
3230
3231    /**
3232     * Helper class for constructor reference lookup. The lookup logic is based
3233     * upon either Resolve.findMethod or Resolve.findDiamond - depending on
3234     * whether the constructor reference needs diamond inference (this is the case
3235     * if the qualifier type is raw). A special erroneous symbol is returned
3236     * if the lookup returns the constructor of an inner class and there's no
3237     * enclosing instance in scope.
3238     */
3239    class ConstructorReferenceLookupHelper extends ReferenceLookupHelper {
3240
3241        boolean needsInference;
3242
3243        ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
3244                List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3245            super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
3246            if (site.isRaw()) {
3247                this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym, site.getMetadata());
3248                needsInference = true;
3249            }
3250        }
3251
3252        @Override
3253        protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3254            Symbol sym = needsInference ?
3255                findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
3256                findMethod(env, site, name, argtypes, typeargtypes,
3257                        phase.isBoxingRequired(), phase.isVarargsRequired());
3258            return enclosingInstanceMissing(env, site) ? new BadConstructorReferenceError(sym) : sym;
3259        }
3260
3261        @Override
3262        ReferenceKind referenceKind(Symbol sym) {
3263            return site.getEnclosingType().hasTag(NONE) ?
3264                    ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER;
3265        }
3266    }
3267
3268    /**
3269     * Main overload resolution routine. On each overload resolution step, a
3270     * lookup helper class is used to perform the method/constructor lookup;
3271     * at the end of the lookup, the helper is used to validate the results
3272     * (this last step might trigger overload resolution diagnostics).
3273     */
3274    Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, MethodCheck methodCheck, LookupHelper lookupHelper) {
3275        MethodResolutionContext resolveContext = new MethodResolutionContext();
3276        resolveContext.methodCheck = methodCheck;
3277        return lookupMethod(env, pos, location, resolveContext, lookupHelper);
3278    }
3279
3280    Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location,
3281            MethodResolutionContext resolveContext, LookupHelper lookupHelper) {
3282        MethodResolutionContext prevResolutionContext = currentResolutionContext;
3283        try {
3284            Symbol bestSoFar = methodNotFound;
3285            currentResolutionContext = resolveContext;
3286            for (MethodResolutionPhase phase : methodResolutionSteps) {
3287                if (lookupHelper.shouldStop(bestSoFar, phase))
3288                    break;
3289                MethodResolutionPhase prevPhase = currentResolutionContext.step;
3290                Symbol prevBest = bestSoFar;
3291                currentResolutionContext.step = phase;
3292                Symbol sym = lookupHelper.lookup(env, phase);
3293                lookupHelper.debug(pos, sym);
3294                bestSoFar = phase.mergeResults(bestSoFar, sym);
3295                env.info.pendingResolutionPhase = (prevBest == bestSoFar) ? prevPhase : phase;
3296            }
3297            return lookupHelper.access(env, pos, location, bestSoFar);
3298        } finally {
3299            currentResolutionContext = prevResolutionContext;
3300        }
3301    }
3302
3303    /**
3304     * Resolve `c.name' where name == this or name == super.
3305     * @param pos           The position to use for error reporting.
3306     * @param env           The environment current at the expression.
3307     * @param c             The qualifier.
3308     * @param name          The identifier's name.
3309     */
3310    Symbol resolveSelf(DiagnosticPosition pos,
3311                       Env<AttrContext> env,
3312                       TypeSymbol c,
3313                       Name name) {
3314        Env<AttrContext> env1 = env;
3315        boolean staticOnly = false;
3316        while (env1.outer != null) {
3317            if (isStatic(env1)) staticOnly = true;
3318            if (env1.enclClass.sym == c) {
3319                Symbol sym = env1.info.scope.findFirst(name);
3320                if (sym != null) {
3321                    if (staticOnly) sym = new StaticError(sym);
3322                    return accessBase(sym, pos, env.enclClass.sym.type,
3323                                  name, true);
3324                }
3325            }
3326            if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3327            env1 = env1.outer;
3328        }
3329        if (c.isInterface() &&
3330            name == names._super && !isStatic(env) &&
3331            types.isDirectSuperInterface(c, env.enclClass.sym)) {
3332            //this might be a default super call if one of the superinterfaces is 'c'
3333            for (Type t : pruneInterfaces(env.enclClass.type)) {
3334                if (t.tsym == c) {
3335                    env.info.defaultSuperCallSite = t;
3336                    return new VarSymbol(0, names._super,
3337                            types.asSuper(env.enclClass.type, c), env.enclClass.sym);
3338                }
3339            }
3340            //find a direct superinterface that is a subtype of 'c'
3341            for (Type i : types.interfaces(env.enclClass.type)) {
3342                if (i.tsym.isSubClass(c, types) && i.tsym != c) {
3343                    log.error(pos, "illegal.default.super.call", c,
3344                            diags.fragment("redundant.supertype", c, i));
3345                    return syms.errSymbol;
3346                }
3347            }
3348            Assert.error();
3349        }
3350        log.error(pos, "not.encl.class", c);
3351        return syms.errSymbol;
3352    }
3353    //where
3354    private List<Type> pruneInterfaces(Type t) {
3355        ListBuffer<Type> result = new ListBuffer<>();
3356        for (Type t1 : types.interfaces(t)) {
3357            boolean shouldAdd = true;
3358            for (Type t2 : types.interfaces(t)) {
3359                if (t1 != t2 && types.isSubtypeNoCapture(t2, t1)) {
3360                    shouldAdd = false;
3361                }
3362            }
3363            if (shouldAdd) {
3364                result.append(t1);
3365            }
3366        }
3367        return result.toList();
3368    }
3369
3370
3371    /**
3372     * Resolve `c.this' for an enclosing class c that contains the
3373     * named member.
3374     * @param pos           The position to use for error reporting.
3375     * @param env           The environment current at the expression.
3376     * @param member        The member that must be contained in the result.
3377     */
3378    Symbol resolveSelfContaining(DiagnosticPosition pos,
3379                                 Env<AttrContext> env,
3380                                 Symbol member,
3381                                 boolean isSuperCall) {
3382        Symbol sym = resolveSelfContainingInternal(env, member, isSuperCall);
3383        if (sym == null) {
3384            log.error(pos, "encl.class.required", member);
3385            return syms.errSymbol;
3386        } else {
3387            return accessBase(sym, pos, env.enclClass.sym.type, sym.name, true);
3388        }
3389    }
3390
3391    boolean enclosingInstanceMissing(Env<AttrContext> env, Type type) {
3392        if (type.hasTag(CLASS) && type.getEnclosingType().hasTag(CLASS)) {
3393            Symbol encl = resolveSelfContainingInternal(env, type.tsym, false);
3394            return encl == null || encl.kind.isResolutionError();
3395        }
3396        return false;
3397    }
3398
3399    private Symbol resolveSelfContainingInternal(Env<AttrContext> env,
3400                                 Symbol member,
3401                                 boolean isSuperCall) {
3402        Name name = names._this;
3403        Env<AttrContext> env1 = isSuperCall ? env.outer : env;
3404        boolean staticOnly = false;
3405        if (env1 != null) {
3406            while (env1 != null && env1.outer != null) {
3407                if (isStatic(env1)) staticOnly = true;
3408                if (env1.enclClass.sym.isSubClass(member.owner.enclClass(), types)) {
3409                    Symbol sym = env1.info.scope.findFirst(name);
3410                    if (sym != null) {
3411                        if (staticOnly) sym = new StaticError(sym);
3412                        return sym;
3413                    }
3414                }
3415                if ((env1.enclClass.sym.flags() & STATIC) != 0)
3416                    staticOnly = true;
3417                env1 = env1.outer;
3418            }
3419        }
3420        return null;
3421    }
3422
3423    /**
3424     * Resolve an appropriate implicit this instance for t's container.
3425     * JLS 8.8.5.1 and 15.9.2
3426     */
3427    Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) {
3428        return resolveImplicitThis(pos, env, t, false);
3429    }
3430
3431    Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t, boolean isSuperCall) {
3432        Type thisType = (t.tsym.owner.kind.matches(KindSelector.VAL_MTH)
3433                         ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this)
3434                         : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type;
3435        if (env.info.isSelfCall && thisType.tsym == env.enclClass.sym)
3436            log.error(pos, "cant.ref.before.ctor.called", "this");
3437        return thisType;
3438    }
3439
3440/* ***************************************************************************
3441 *  ResolveError classes, indicating error situations when accessing symbols
3442 ****************************************************************************/
3443
3444    //used by TransTypes when checking target type of synthetic cast
3445    public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
3446        AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
3447        logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
3448    }
3449    //where
3450    private void logResolveError(ResolveError error,
3451            DiagnosticPosition pos,
3452            Symbol location,
3453            Type site,
3454            Name name,
3455            List<Type> argtypes,
3456            List<Type> typeargtypes) {
3457        JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
3458                pos, location, site, name, argtypes, typeargtypes);
3459        if (d != null) {
3460            d.setFlag(DiagnosticFlag.RESOLVE_ERROR);
3461            log.report(d);
3462        }
3463    }
3464
3465    private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
3466
3467    public Object methodArguments(List<Type> argtypes) {
3468        if (argtypes == null || argtypes.isEmpty()) {
3469            return noArgs;
3470        } else {
3471            ListBuffer<Object> diagArgs = new ListBuffer<>();
3472            for (Type t : argtypes) {
3473                if (t.hasTag(DEFERRED)) {
3474                    diagArgs.append(((DeferredAttr.DeferredType)t).tree);
3475                } else {
3476                    diagArgs.append(t);
3477                }
3478            }
3479            return diagArgs;
3480        }
3481    }
3482
3483    /**
3484     * Root class for resolution errors. Subclass of ResolveError
3485     * represent a different kinds of resolution error - as such they must
3486     * specify how they map into concrete compiler diagnostics.
3487     */
3488    abstract class ResolveError extends Symbol {
3489
3490        /** The name of the kind of error, for debugging only. */
3491        final String debugName;
3492
3493        ResolveError(Kind kind, String debugName) {
3494            super(kind, 0, null, null, null);
3495            this.debugName = debugName;
3496        }
3497
3498        @Override @DefinedBy(Api.LANGUAGE_MODEL)
3499        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
3500            throw new AssertionError();
3501        }
3502
3503        @Override
3504        public String toString() {
3505            return debugName;
3506        }
3507
3508        @Override
3509        public boolean exists() {
3510            return false;
3511        }
3512
3513        @Override
3514        public boolean isStatic() {
3515            return false;
3516        }
3517
3518        /**
3519         * Create an external representation for this erroneous symbol to be
3520         * used during attribution - by default this returns the symbol of a
3521         * brand new error type which stores the original type found
3522         * during resolution.
3523         *
3524         * @param name     the name used during resolution
3525         * @param location the location from which the symbol is accessed
3526         */
3527        protected Symbol access(Name name, TypeSymbol location) {
3528            return types.createErrorType(name, location, syms.errSymbol.type).tsym;
3529        }
3530
3531        /**
3532         * Create a diagnostic representing this resolution error.
3533         *
3534         * @param dkind     The kind of the diagnostic to be created (e.g error).
3535         * @param pos       The position to be used for error reporting.
3536         * @param site      The original type from where the selection took place.
3537         * @param name      The name of the symbol to be resolved.
3538         * @param argtypes  The invocation's value arguments,
3539         *                  if we looked for a method.
3540         * @param typeargtypes  The invocation's type arguments,
3541         *                      if we looked for a method.
3542         */
3543        abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3544                DiagnosticPosition pos,
3545                Symbol location,
3546                Type site,
3547                Name name,
3548                List<Type> argtypes,
3549                List<Type> typeargtypes);
3550    }
3551
3552    /**
3553     * This class is the root class of all resolution errors caused by
3554     * an invalid symbol being found during resolution.
3555     */
3556    abstract class InvalidSymbolError extends ResolveError {
3557
3558        /** The invalid symbol found during resolution */
3559        Symbol sym;
3560
3561        InvalidSymbolError(Kind kind, Symbol sym, String debugName) {
3562            super(kind, debugName);
3563            this.sym = sym;
3564        }
3565
3566        @Override
3567        public boolean exists() {
3568            return true;
3569        }
3570
3571        @Override
3572        public String toString() {
3573             return super.toString() + " wrongSym=" + sym;
3574        }
3575
3576        @Override
3577        public Symbol access(Name name, TypeSymbol location) {
3578            if (!sym.kind.isResolutionError() && sym.kind.matches(KindSelector.TYP))
3579                return types.createErrorType(name, location, sym.type).tsym;
3580            else
3581                return sym;
3582        }
3583    }
3584
3585    /**
3586     * InvalidSymbolError error class indicating that a symbol matching a
3587     * given name does not exists in a given site.
3588     */
3589    class SymbolNotFoundError extends ResolveError {
3590
3591        SymbolNotFoundError(Kind kind) {
3592            this(kind, "symbol not found error");
3593        }
3594
3595        SymbolNotFoundError(Kind kind, String debugName) {
3596            super(kind, debugName);
3597        }
3598
3599        @Override
3600        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3601                DiagnosticPosition pos,
3602                Symbol location,
3603                Type site,
3604                Name name,
3605                List<Type> argtypes,
3606                List<Type> typeargtypes) {
3607            argtypes = argtypes == null ? List.<Type>nil() : argtypes;
3608            typeargtypes = typeargtypes == null ? List.<Type>nil() : typeargtypes;
3609            if (name == names.error)
3610                return null;
3611
3612            boolean hasLocation = false;
3613            if (location == null) {
3614                location = site.tsym;
3615            }
3616            if (!location.name.isEmpty()) {
3617                if (location.kind == PCK && !site.tsym.exists()) {
3618                    return diags.create(dkind, log.currentSource(), pos,
3619                        "doesnt.exist", location);
3620                }
3621                hasLocation = !location.name.equals(names._this) &&
3622                        !location.name.equals(names._super);
3623            }
3624            boolean isConstructor = name == names.init;
3625            KindName kindname = isConstructor ? KindName.CONSTRUCTOR : kind.absentKind();
3626            Name idname = isConstructor ? site.tsym.name : name;
3627            String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
3628            if (hasLocation) {
3629                return diags.create(dkind, log.currentSource(), pos,
3630                        errKey, kindname, idname, //symbol kindname, name
3631                        typeargtypes, args(argtypes), //type parameters and arguments (if any)
3632                        getLocationDiag(location, site)); //location kindname, type
3633            }
3634            else {
3635                return diags.create(dkind, log.currentSource(), pos,
3636                        errKey, kindname, idname, //symbol kindname, name
3637                        typeargtypes, args(argtypes)); //type parameters and arguments (if any)
3638            }
3639        }
3640        //where
3641        private Object args(List<Type> args) {
3642            return args.isEmpty() ? args : methodArguments(args);
3643        }
3644
3645        private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) {
3646            String key = "cant.resolve";
3647            String suffix = hasLocation ? ".location" : "";
3648            switch (kindname) {
3649                case METHOD:
3650                case CONSTRUCTOR: {
3651                    suffix += ".args";
3652                    suffix += hasTypeArgs ? ".params" : "";
3653                }
3654            }
3655            return key + suffix;
3656        }
3657        private JCDiagnostic getLocationDiag(Symbol location, Type site) {
3658            if (location.kind == VAR) {
3659                return diags.fragment("location.1",
3660                    kindName(location),
3661                    location,
3662                    location.type);
3663            } else {
3664                return diags.fragment("location",
3665                    typeKindName(site),
3666                    site,
3667                    null);
3668            }
3669        }
3670    }
3671
3672    /**
3673     * InvalidSymbolError error class indicating that a given symbol
3674     * (either a method, a constructor or an operand) is not applicable
3675     * given an actual arguments/type argument list.
3676     */
3677    class InapplicableSymbolError extends ResolveError {
3678
3679        protected MethodResolutionContext resolveContext;
3680
3681        InapplicableSymbolError(MethodResolutionContext context) {
3682            this(WRONG_MTH, "inapplicable symbol error", context);
3683        }
3684
3685        protected InapplicableSymbolError(Kind kind, String debugName, MethodResolutionContext context) {
3686            super(kind, debugName);
3687            this.resolveContext = context;
3688        }
3689
3690        @Override
3691        public String toString() {
3692            return super.toString();
3693        }
3694
3695        @Override
3696        public boolean exists() {
3697            return true;
3698        }
3699
3700        @Override
3701        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3702                DiagnosticPosition pos,
3703                Symbol location,
3704                Type site,
3705                Name name,
3706                List<Type> argtypes,
3707                List<Type> typeargtypes) {
3708            if (name == names.error)
3709                return null;
3710
3711            Pair<Symbol, JCDiagnostic> c = errCandidate();
3712            if (compactMethodDiags) {
3713                JCDiagnostic simpleDiag =
3714                    MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd);
3715                if (simpleDiag != null) {
3716                    return simpleDiag;
3717                }
3718            }
3719            Symbol ws = c.fst.asMemberOf(site, types);
3720            return diags.create(dkind, log.currentSource(), pos,
3721                      "cant.apply.symbol",
3722                      kindName(ws),
3723                      ws.name == names.init ? ws.owner.name : ws.name,
3724                      methodArguments(ws.type.getParameterTypes()),
3725                      methodArguments(argtypes),
3726                      kindName(ws.owner),
3727                      ws.owner.type,
3728                      c.snd);
3729        }
3730
3731        @Override
3732        public Symbol access(Name name, TypeSymbol location) {
3733            return types.createErrorType(name, location, syms.errSymbol.type).tsym;
3734        }
3735
3736        protected Pair<Symbol, JCDiagnostic> errCandidate() {
3737            Candidate bestSoFar = null;
3738            for (Candidate c : resolveContext.candidates) {
3739                if (c.isApplicable()) continue;
3740                bestSoFar = c;
3741            }
3742            Assert.checkNonNull(bestSoFar);
3743            return new Pair<>(bestSoFar.sym, bestSoFar.details);
3744        }
3745    }
3746
3747    /**
3748     * ResolveError error class indicating that a symbol (either methods, constructors or operand)
3749     * is not applicable given an actual arguments/type argument list.
3750     */
3751    class InapplicableSymbolsError extends InapplicableSymbolError {
3752
3753        InapplicableSymbolsError(MethodResolutionContext context) {
3754            super(WRONG_MTHS, "inapplicable symbols", context);
3755        }
3756
3757        @Override
3758        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3759                DiagnosticPosition pos,
3760                Symbol location,
3761                Type site,
3762                Name name,
3763                List<Type> argtypes,
3764                List<Type> typeargtypes) {
3765            Map<Symbol, JCDiagnostic> candidatesMap = mapCandidates();
3766            Map<Symbol, JCDiagnostic> filteredCandidates = compactMethodDiags ?
3767                    filterCandidates(candidatesMap) :
3768                    mapCandidates();
3769            if (filteredCandidates.isEmpty()) {
3770                filteredCandidates = candidatesMap;
3771            }
3772            boolean truncatedDiag = candidatesMap.size() != filteredCandidates.size();
3773            if (filteredCandidates.size() > 1) {
3774                JCDiagnostic err = diags.create(dkind,
3775                        null,
3776                        truncatedDiag ?
3777                            EnumSet.of(DiagnosticFlag.COMPRESSED) :
3778                            EnumSet.noneOf(DiagnosticFlag.class),
3779                        log.currentSource(),
3780                        pos,
3781                        "cant.apply.symbols",
3782                        name == names.init ? KindName.CONSTRUCTOR : kind.absentKind(),
3783                        name == names.init ? site.tsym.name : name,
3784                        methodArguments(argtypes));
3785                return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(filteredCandidates, site));
3786            } else if (filteredCandidates.size() == 1) {
3787                Map.Entry<Symbol, JCDiagnostic> _e =
3788                                filteredCandidates.entrySet().iterator().next();
3789                final Pair<Symbol, JCDiagnostic> p = new Pair<>(_e.getKey(), _e.getValue());
3790                JCDiagnostic d = new InapplicableSymbolError(resolveContext) {
3791                    @Override
3792                    protected Pair<Symbol, JCDiagnostic> errCandidate() {
3793                        return p;
3794                    }
3795                }.getDiagnostic(dkind, pos,
3796                    location, site, name, argtypes, typeargtypes);
3797                if (truncatedDiag) {
3798                    d.setFlag(DiagnosticFlag.COMPRESSED);
3799                }
3800                return d;
3801            } else {
3802                return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
3803                    location, site, name, argtypes, typeargtypes);
3804            }
3805        }
3806        //where
3807            private Map<Symbol, JCDiagnostic> mapCandidates() {
3808                Map<Symbol, JCDiagnostic> candidates = new LinkedHashMap<>();
3809                for (Candidate c : resolveContext.candidates) {
3810                    if (c.isApplicable()) continue;
3811                    candidates.put(c.sym, c.details);
3812                }
3813                return candidates;
3814            }
3815
3816            Map<Symbol, JCDiagnostic> filterCandidates(Map<Symbol, JCDiagnostic> candidatesMap) {
3817                Map<Symbol, JCDiagnostic> candidates = new LinkedHashMap<>();
3818                for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) {
3819                    JCDiagnostic d = _entry.getValue();
3820                    if (!new Template(MethodCheckDiag.ARITY_MISMATCH.regex()).matches(d)) {
3821                        candidates.put(_entry.getKey(), d);
3822                    }
3823                }
3824                return candidates;
3825            }
3826
3827            private List<JCDiagnostic> candidateDetails(Map<Symbol, JCDiagnostic> candidatesMap, Type site) {
3828                List<JCDiagnostic> details = List.nil();
3829                for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) {
3830                    Symbol sym = _entry.getKey();
3831                    JCDiagnostic detailDiag = diags.fragment("inapplicable.method",
3832                            Kinds.kindName(sym),
3833                            sym.location(site, types),
3834                            sym.asMemberOf(site, types),
3835                            _entry.getValue());
3836                    details = details.prepend(detailDiag);
3837                }
3838                //typically members are visited in reverse order (see Scope)
3839                //so we need to reverse the candidate list so that candidates
3840                //conform to source order
3841                return details;
3842            }
3843    }
3844
3845    /**
3846     * DiamondError error class indicating that a constructor symbol is not applicable
3847     * given an actual arguments/type argument list using diamond inference.
3848     */
3849    class DiamondError extends InapplicableSymbolError {
3850
3851        Symbol sym;
3852
3853        public DiamondError(Symbol sym, MethodResolutionContext context) {
3854            super(sym.kind, "diamondError", context);
3855            this.sym = sym;
3856        }
3857
3858        JCDiagnostic getDetails() {
3859            return (sym.kind == WRONG_MTH) ?
3860                    ((InapplicableSymbolError)sym.baseSymbol()).errCandidate().snd :
3861                    null;
3862        }
3863
3864        @Override
3865        JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
3866                Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
3867            JCDiagnostic details = getDetails();
3868            if (details != null && compactMethodDiags) {
3869                JCDiagnostic simpleDiag =
3870                        MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, details);
3871                if (simpleDiag != null) {
3872                    return simpleDiag;
3873                }
3874            }
3875            String key = details == null ?
3876                "cant.apply.diamond" :
3877                "cant.apply.diamond.1";
3878            return diags.create(dkind, log.currentSource(), pos, key,
3879                    diags.fragment("diamond", site.tsym), details);
3880        }
3881    }
3882
3883    /**
3884     * An InvalidSymbolError error class indicating that a symbol is not
3885     * accessible from a given site
3886     */
3887    class AccessError extends InvalidSymbolError {
3888
3889        private Env<AttrContext> env;
3890        private Type site;
3891
3892        AccessError(Symbol sym) {
3893            this(null, null, sym);
3894        }
3895
3896        AccessError(Env<AttrContext> env, Type site, Symbol sym) {
3897            super(HIDDEN, sym, "access error");
3898            this.env = env;
3899            this.site = site;
3900            if (debugResolve)
3901                log.error("proc.messager", sym + " @ " + site + " is inaccessible.");
3902        }
3903
3904        @Override
3905        public boolean exists() {
3906            return false;
3907        }
3908
3909        @Override
3910        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3911                DiagnosticPosition pos,
3912                Symbol location,
3913                Type site,
3914                Name name,
3915                List<Type> argtypes,
3916                List<Type> typeargtypes) {
3917            if (sym.owner.type.hasTag(ERROR))
3918                return null;
3919
3920            if (sym.name == names.init && sym.owner != site.tsym) {
3921                return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind,
3922                        pos, location, site, name, argtypes, typeargtypes);
3923            }
3924            else if ((sym.flags() & PUBLIC) != 0
3925                || (env != null && this.site != null
3926                    && !isAccessible(env, this.site))) {
3927                return diags.create(dkind, log.currentSource(),
3928                        pos, "not.def.access.class.intf.cant.access",
3929                    sym, sym.location());
3930            }
3931            else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) {
3932                return diags.create(dkind, log.currentSource(),
3933                        pos, "report.access", sym,
3934                        asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
3935                        sym.location());
3936            }
3937            else {
3938                return diags.create(dkind, log.currentSource(),
3939                        pos, "not.def.public.cant.access", sym, sym.location());
3940            }
3941        }
3942    }
3943
3944    /**
3945     * InvalidSymbolError error class indicating that an instance member
3946     * has erroneously been accessed from a static context.
3947     */
3948    class StaticError extends InvalidSymbolError {
3949
3950        StaticError(Symbol sym) {
3951            super(STATICERR, sym, "static error");
3952        }
3953
3954        @Override
3955        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3956                DiagnosticPosition pos,
3957                Symbol location,
3958                Type site,
3959                Name name,
3960                List<Type> argtypes,
3961                List<Type> typeargtypes) {
3962            Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS))
3963                ? types.erasure(sym.type).tsym
3964                : sym);
3965            return diags.create(dkind, log.currentSource(), pos,
3966                    "non-static.cant.be.ref", kindName(sym), errSym);
3967        }
3968    }
3969
3970    /**
3971     * InvalidSymbolError error class indicating that a pair of symbols
3972     * (either methods, constructors or operands) are ambiguous
3973     * given an actual arguments/type argument list.
3974     */
3975    class AmbiguityError extends ResolveError {
3976
3977        /** The other maximally specific symbol */
3978        List<Symbol> ambiguousSyms = List.nil();
3979
3980        @Override
3981        public boolean exists() {
3982            return true;
3983        }
3984
3985        AmbiguityError(Symbol sym1, Symbol sym2) {
3986            super(AMBIGUOUS, "ambiguity error");
3987            ambiguousSyms = flatten(sym2).appendList(flatten(sym1));
3988        }
3989
3990        private List<Symbol> flatten(Symbol sym) {
3991            if (sym.kind == AMBIGUOUS) {
3992                return ((AmbiguityError)sym.baseSymbol()).ambiguousSyms;
3993            } else {
3994                return List.of(sym);
3995            }
3996        }
3997
3998        AmbiguityError addAmbiguousSymbol(Symbol s) {
3999            ambiguousSyms = ambiguousSyms.prepend(s);
4000            return this;
4001        }
4002
4003        @Override
4004        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4005                DiagnosticPosition pos,
4006                Symbol location,
4007                Type site,
4008                Name name,
4009                List<Type> argtypes,
4010                List<Type> typeargtypes) {
4011            List<Symbol> diagSyms = ambiguousSyms.reverse();
4012            Symbol s1 = diagSyms.head;
4013            Symbol s2 = diagSyms.tail.head;
4014            Name sname = s1.name;
4015            if (sname == names.init) sname = s1.owner.name;
4016            return diags.create(dkind, log.currentSource(),
4017                    pos, "ref.ambiguous", sname,
4018                    kindName(s1),
4019                    s1,
4020                    s1.location(site, types),
4021                    kindName(s2),
4022                    s2,
4023                    s2.location(site, types));
4024        }
4025
4026        /**
4027         * If multiple applicable methods are found during overload and none of them
4028         * is more specific than the others, attempt to merge their signatures.
4029         */
4030        Symbol mergeAbstracts(Type site) {
4031            List<Symbol> ambiguousInOrder = ambiguousSyms.reverse();
4032            for (Symbol s : ambiguousInOrder) {
4033                Type mt = types.memberType(site, s);
4034                boolean found = true;
4035                List<Type> allThrown = mt.getThrownTypes();
4036                for (Symbol s2 : ambiguousInOrder) {
4037                    Type mt2 = types.memberType(site, s2);
4038                    if ((s2.flags() & ABSTRACT) == 0 ||
4039                        !types.overrideEquivalent(mt, mt2) ||
4040                        !types.isSameTypes(s.erasure(types).getParameterTypes(),
4041                                       s2.erasure(types).getParameterTypes())) {
4042                        //ambiguity cannot be resolved
4043                        return this;
4044                    }
4045                    Type mst = mostSpecificReturnType(mt, mt2);
4046                    if (mst == null || mst != mt) {
4047                        found = false;
4048                        break;
4049                    }
4050                    allThrown = chk.intersect(allThrown, mt2.getThrownTypes());
4051                }
4052                if (found) {
4053                    //all ambiguous methods were abstract and one method had
4054                    //most specific return type then others
4055                    return (allThrown == mt.getThrownTypes()) ?
4056                            s : new MethodSymbol(
4057                                s.flags(),
4058                                s.name,
4059                                types.createMethodTypeWithThrown(s.type, allThrown),
4060                                s.owner);
4061                }
4062            }
4063            return this;
4064        }
4065
4066        @Override
4067        protected Symbol access(Name name, TypeSymbol location) {
4068            Symbol firstAmbiguity = ambiguousSyms.last();
4069            return firstAmbiguity.kind == TYP ?
4070                    types.createErrorType(name, location, firstAmbiguity.type).tsym :
4071                    firstAmbiguity;
4072        }
4073    }
4074
4075    class BadVarargsMethod extends ResolveError {
4076
4077        ResolveError delegatedError;
4078
4079        BadVarargsMethod(ResolveError delegatedError) {
4080            super(delegatedError.kind, "badVarargs");
4081            this.delegatedError = delegatedError;
4082        }
4083
4084        @Override
4085        public Symbol baseSymbol() {
4086            return delegatedError.baseSymbol();
4087        }
4088
4089        @Override
4090        protected Symbol access(Name name, TypeSymbol location) {
4091            return delegatedError.access(name, location);
4092        }
4093
4094        @Override
4095        public boolean exists() {
4096            return true;
4097        }
4098
4099        @Override
4100        JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4101            return delegatedError.getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes);
4102        }
4103    }
4104
4105    /**
4106     * BadMethodReferenceError error class indicating that a method reference symbol has been found,
4107     * but with the wrong staticness.
4108     */
4109    class BadMethodReferenceError extends StaticError {
4110
4111        boolean unboundLookup;
4112
4113        public BadMethodReferenceError(Symbol sym, boolean unboundLookup) {
4114            super(sym);
4115            this.unboundLookup = unboundLookup;
4116        }
4117
4118        @Override
4119        JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4120            final String key;
4121            if (!unboundLookup) {
4122                key = "bad.static.method.in.bound.lookup";
4123            } else if (sym.isStatic()) {
4124                key = "bad.static.method.in.unbound.lookup";
4125            } else {
4126                key = "bad.instance.method.in.unbound.lookup";
4127            }
4128            return sym.kind.isResolutionError() ?
4129                    ((ResolveError)sym).getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes) :
4130                    diags.create(dkind, log.currentSource(), pos, key, Kinds.kindName(sym), sym);
4131        }
4132    }
4133
4134    /**
4135     * BadConstructorReferenceError error class indicating that a constructor reference symbol has been found,
4136     * but pointing to a class for which an enclosing instance is not available.
4137     */
4138    class BadConstructorReferenceError extends InvalidSymbolError {
4139
4140        public BadConstructorReferenceError(Symbol sym) {
4141            super(MISSING_ENCL, sym, "BadConstructorReferenceError");
4142        }
4143
4144        @Override
4145        JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4146           return diags.create(dkind, log.currentSource(), pos,
4147                "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType());
4148        }
4149    }
4150
4151    /**
4152     * Helper class for method resolution diagnostic simplification.
4153     * Certain resolution diagnostic are rewritten as simpler diagnostic
4154     * where the enclosing resolution diagnostic (i.e. 'inapplicable method')
4155     * is stripped away, as it doesn't carry additional info. The logic
4156     * for matching a given diagnostic is given in terms of a template
4157     * hierarchy: a diagnostic template can be specified programmatically,
4158     * so that only certain diagnostics are matched. Each templete is then
4159     * associated with a rewriter object that carries out the task of rewtiting
4160     * the diagnostic to a simpler one.
4161     */
4162    static class MethodResolutionDiagHelper {
4163
4164        /**
4165         * A diagnostic rewriter transforms a method resolution diagnostic
4166         * into a simpler one
4167         */
4168        interface DiagnosticRewriter {
4169            JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
4170                    DiagnosticPosition preferedPos, DiagnosticSource preferredSource,
4171                    DiagnosticType preferredKind, JCDiagnostic d);
4172        }
4173
4174        /**
4175         * A diagnostic template is made up of two ingredients: (i) a regular
4176         * expression for matching a diagnostic key and (ii) a list of sub-templates
4177         * for matching diagnostic arguments.
4178         */
4179        static class Template {
4180
4181            /** regex used to match diag key */
4182            String regex;
4183
4184            /** templates used to match diagnostic args */
4185            Template[] subTemplates;
4186
4187            Template(String key, Template... subTemplates) {
4188                this.regex = key;
4189                this.subTemplates = subTemplates;
4190            }
4191
4192            /**
4193             * Returns true if the regex matches the diagnostic key and if
4194             * all diagnostic arguments are matches by corresponding sub-templates.
4195             */
4196            boolean matches(Object o) {
4197                JCDiagnostic d = (JCDiagnostic)o;
4198                Object[] args = d.getArgs();
4199                if (!d.getCode().matches(regex) ||
4200                        subTemplates.length != d.getArgs().length) {
4201                    return false;
4202                }
4203                for (int i = 0; i < args.length ; i++) {
4204                    if (!subTemplates[i].matches(args[i])) {
4205                        return false;
4206                    }
4207                }
4208                return true;
4209            }
4210        }
4211
4212        /**
4213         * Common rewriter for all argument mismatch simplifications.
4214         */
4215        static class ArgMismatchRewriter implements DiagnosticRewriter {
4216
4217            /** the index of the subdiagnostic to be used as primary. */
4218            int causeIndex;
4219
4220            public ArgMismatchRewriter(int causeIndex) {
4221                this.causeIndex = causeIndex;
4222            }
4223
4224            @Override
4225            public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
4226                    DiagnosticPosition preferedPos, DiagnosticSource preferredSource,
4227                    DiagnosticType preferredKind, JCDiagnostic d) {
4228                JCDiagnostic cause = (JCDiagnostic)d.getArgs()[causeIndex];
4229                DiagnosticPosition pos = d.getDiagnosticPosition();
4230                if (pos == null) {
4231                    pos = preferedPos;
4232                }
4233                return diags.create(preferredKind, preferredSource, pos,
4234                        "prob.found.req", cause);
4235            }
4236        }
4237
4238        /** a dummy template that match any diagnostic argument */
4239        static final Template skip = new Template("") {
4240            @Override
4241            boolean matches(Object d) {
4242                return true;
4243            }
4244        };
4245
4246        /** template for matching inference-free arguments mismatch failures */
4247        static final Template argMismatchTemplate = new Template(MethodCheckDiag.ARG_MISMATCH.regex(), skip);
4248
4249        /** template for matching inference related arguments mismatch failures */
4250        static final Template inferArgMismatchTemplate = new Template(MethodCheckDiag.ARG_MISMATCH.regex(), skip, skip) {
4251            @Override
4252            boolean matches(Object o) {
4253                if (!super.matches(o)) {
4254                    return false;
4255                }
4256                JCDiagnostic d = (JCDiagnostic)o;
4257                @SuppressWarnings("unchecked")
4258                List<Type> tvars = (List<Type>)d.getArgs()[0];
4259                return !containsAny(d, tvars);
4260            }
4261
4262            BiPredicate<Object, List<Type>> containsPredicate = (o, ts) -> {
4263                if (o instanceof Type) {
4264                    return ((Type)o).containsAny(ts);
4265                } else if (o instanceof JCDiagnostic) {
4266                    return containsAny((JCDiagnostic)o, ts);
4267                } else {
4268                    return false;
4269                }
4270            };
4271
4272            boolean containsAny(JCDiagnostic d, List<Type> ts) {
4273                return Stream.of(d.getArgs())
4274                        .anyMatch(o -> containsPredicate.test(o, ts));
4275            }
4276        };
4277
4278        /** rewriter map used for method resolution simplification */
4279        static final Map<Template, DiagnosticRewriter> rewriters = new LinkedHashMap<>();
4280
4281        static {
4282            rewriters.put(argMismatchTemplate, new ArgMismatchRewriter(0));
4283            rewriters.put(inferArgMismatchTemplate, new ArgMismatchRewriter(1));
4284        }
4285
4286        /**
4287         * Main entry point for diagnostic rewriting - given a diagnostic, see if any templates matches it,
4288         * and rewrite it accordingly.
4289         */
4290        static JCDiagnostic rewrite(JCDiagnostic.Factory diags, DiagnosticPosition pos, DiagnosticSource source,
4291                                    DiagnosticType dkind, JCDiagnostic d) {
4292            for (Map.Entry<Template, DiagnosticRewriter> _entry : rewriters.entrySet()) {
4293                if (_entry.getKey().matches(d)) {
4294                    JCDiagnostic simpleDiag =
4295                            _entry.getValue().rewriteDiagnostic(diags, pos, source, dkind, d);
4296                    simpleDiag.setFlag(DiagnosticFlag.COMPRESSED);
4297                    return simpleDiag;
4298                }
4299            }
4300            return null;
4301        }
4302    }
4303
4304    enum MethodResolutionPhase {
4305        BASIC(false, false),
4306        BOX(true, false),
4307        VARARITY(true, true) {
4308            @Override
4309            public Symbol mergeResults(Symbol bestSoFar, Symbol sym) {
4310                //Check invariants (see {@code LookupHelper.shouldStop})
4311                Assert.check(bestSoFar.kind.isResolutionError() && bestSoFar.kind != AMBIGUOUS);
4312                if (!sym.kind.isResolutionError()) {
4313                    //varargs resolution successful
4314                    return sym;
4315                } else {
4316                    //pick best error
4317                    switch (bestSoFar.kind) {
4318                        case WRONG_MTH:
4319                        case WRONG_MTHS:
4320                            //Override previous errors if they were caused by argument mismatch.
4321                            //This generally means preferring current symbols - but we need to pay
4322                            //attention to the fact that the varargs lookup returns 'less' candidates
4323                            //than the previous rounds, and adjust that accordingly.
4324                            switch (sym.kind) {
4325                                case WRONG_MTH:
4326                                    //if the previous round matched more than one method, return that
4327                                    //result instead
4328                                    return bestSoFar.kind == WRONG_MTHS ?
4329                                            bestSoFar : sym;
4330                                case ABSENT_MTH:
4331                                    //do not override erroneous symbol if the arity lookup did not
4332                                    //match any method
4333                                    return bestSoFar;
4334                                case WRONG_MTHS:
4335                                default:
4336                                    //safe to override
4337                                    return sym;
4338                            }
4339                        default:
4340                            //otherwise, return first error
4341                            return bestSoFar;
4342                    }
4343                }
4344            }
4345        };
4346
4347        final boolean isBoxingRequired;
4348        final boolean isVarargsRequired;
4349
4350        MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) {
4351           this.isBoxingRequired = isBoxingRequired;
4352           this.isVarargsRequired = isVarargsRequired;
4353        }
4354
4355        public boolean isBoxingRequired() {
4356            return isBoxingRequired;
4357        }
4358
4359        public boolean isVarargsRequired() {
4360            return isVarargsRequired;
4361        }
4362
4363        public Symbol mergeResults(Symbol prev, Symbol sym) {
4364            return sym;
4365        }
4366    }
4367
4368    final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
4369
4370    /**
4371     * A resolution context is used to keep track of intermediate results of
4372     * overload resolution, such as list of method that are not applicable
4373     * (used to generate more precise diagnostics) and so on. Resolution contexts
4374     * can be nested - this means that when each overload resolution routine should
4375     * work within the resolution context it created.
4376     */
4377    class MethodResolutionContext {
4378
4379        private List<Candidate> candidates = List.nil();
4380
4381        MethodResolutionPhase step = null;
4382
4383        MethodCheck methodCheck = resolveMethodCheck;
4384
4385        private boolean internalResolution = false;
4386        private DeferredAttr.AttrMode attrMode = DeferredAttr.AttrMode.SPECULATIVE;
4387
4388        void addInapplicableCandidate(Symbol sym, JCDiagnostic details) {
4389            Candidate c = new Candidate(currentResolutionContext.step, sym, details, null);
4390            candidates = candidates.append(c);
4391        }
4392
4393        void addApplicableCandidate(Symbol sym, Type mtype) {
4394            Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype);
4395            candidates = candidates.append(c);
4396        }
4397
4398        DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext, ResultInfo pendingResult, Warner warn) {
4399            DeferredAttrContext parent = (pendingResult == null)
4400                ? deferredAttr.emptyDeferredAttrContext
4401                : pendingResult.checkContext.deferredAttrContext();
4402            return deferredAttr.new DeferredAttrContext(attrMode, sym, step,
4403                    inferenceContext, parent, warn);
4404        }
4405
4406        /**
4407         * This class represents an overload resolution candidate. There are two
4408         * kinds of candidates: applicable methods and inapplicable methods;
4409         * applicable methods have a pointer to the instantiated method type,
4410         * while inapplicable candidates contain further details about the
4411         * reason why the method has been considered inapplicable.
4412         */
4413        @SuppressWarnings("overrides")
4414        class Candidate {
4415
4416            final MethodResolutionPhase step;
4417            final Symbol sym;
4418            final JCDiagnostic details;
4419            final Type mtype;
4420
4421            private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
4422                this.step = step;
4423                this.sym = sym;
4424                this.details = details;
4425                this.mtype = mtype;
4426            }
4427
4428            @Override
4429            public boolean equals(Object o) {
4430                if (o instanceof Candidate) {
4431                    Symbol s1 = this.sym;
4432                    Symbol s2 = ((Candidate)o).sym;
4433                    if  ((s1 != s2 &&
4434                            (s1.overrides(s2, s1.owner.type.tsym, types, false) ||
4435                            (s2.overrides(s1, s2.owner.type.tsym, types, false)))) ||
4436                            ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner))
4437                        return true;
4438                }
4439                return false;
4440            }
4441
4442            boolean isApplicable() {
4443                return mtype != null;
4444            }
4445        }
4446
4447        DeferredAttr.AttrMode attrMode() {
4448            return attrMode;
4449        }
4450
4451        boolean internal() {
4452            return internalResolution;
4453        }
4454    }
4455
4456    MethodResolutionContext currentResolutionContext = null;
4457}
4458