Resolve.java revision 3243:645b5debcb07
1106813Ssimokawa/*
2113584Ssimokawa * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
3106813Ssimokawa * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4106813Ssimokawa *
5106813Ssimokawa * This code is free software; you can redistribute it and/or modify it
6106813Ssimokawa * under the terms of the GNU General Public License version 2 only, as
7106813Ssimokawa * published by the Free Software Foundation.  Oracle designates this
8106813Ssimokawa * particular file as subject to the "Classpath" exception as provided
9106813Ssimokawa * by Oracle in the LICENSE file that accompanied this code.
10106813Ssimokawa *
11106813Ssimokawa * This code is distributed in the hope that it will be useful, but WITHOUT
12106813Ssimokawa * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13106813Ssimokawa * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14106813Ssimokawa * version 2 for more details (a copy is included in the LICENSE file that
15106813Ssimokawa * accompanied this code).
16106813Ssimokawa *
17106813Ssimokawa * You should have received a copy of the GNU General Public License version
18106813Ssimokawa * 2 along with this work; if not, write to the Free Software Foundation,
19106813Ssimokawa * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20106813Ssimokawa *
21106813Ssimokawa * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22106813Ssimokawa * or visit www.oracle.com if you need additional information or have any
23106813Ssimokawa * questions.
24106813Ssimokawa */
25106813Ssimokawa
26106813Ssimokawapackage com.sun.tools.javac.comp;
27106813Ssimokawa
28106813Ssimokawaimport com.sun.tools.javac.api.Formattable.LocalizedString;
29106813Ssimokawaimport com.sun.tools.javac.code.*;
30106813Ssimokawaimport com.sun.tools.javac.code.Scope.WriteableScope;
31106813Ssimokawaimport com.sun.tools.javac.code.Symbol.*;
32106813Ssimokawaimport com.sun.tools.javac.code.Type.*;
33106813Ssimokawaimport com.sun.tools.javac.comp.Attr.ResultInfo;
34106813Ssimokawaimport com.sun.tools.javac.comp.Check.CheckContext;
35106813Ssimokawaimport com.sun.tools.javac.comp.DeferredAttr.AttrMode;
36106813Ssimokawaimport com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
37106813Ssimokawaimport com.sun.tools.javac.comp.DeferredAttr.DeferredType;
38106813Ssimokawaimport com.sun.tools.javac.comp.Infer.FreeTypeListener;
39106813Ssimokawaimport com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
40106813Ssimokawaimport com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template;
41106813Ssimokawaimport com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind;
42120660Ssimokawaimport com.sun.tools.javac.jvm.*;
43120660Ssimokawaimport com.sun.tools.javac.main.Option;
44120660Ssimokawaimport com.sun.tools.javac.tree.*;
45120660Ssimokawaimport com.sun.tools.javac.tree.JCTree.*;
46120660Ssimokawaimport com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
47106813Ssimokawaimport com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
48106813Ssimokawaimport com.sun.tools.javac.util.*;
49106813Ssimokawaimport com.sun.tools.javac.util.DefinedBy.Api;
50106813Ssimokawaimport com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
51106813Ssimokawaimport com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
52106813Ssimokawaimport com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
53106813Ssimokawa
54118455Ssimokawaimport java.util.Arrays;
55113584Ssimokawaimport java.util.Collection;
56106813Ssimokawaimport java.util.EnumSet;
57106813Ssimokawaimport java.util.Iterator;
58106813Ssimokawaimport java.util.LinkedHashMap;
59106813Ssimokawaimport java.util.Map;
60106813Ssimokawaimport java.util.function.BiPredicate;
61113584Ssimokawaimport java.util.stream.Stream;
62106813Ssimokawa
63109282Ssimokawaimport javax.lang.model.element.ElementVisitor;
64106813Ssimokawa
65106813Ssimokawaimport static com.sun.tools.javac.code.Flags.*;
66106813Ssimokawaimport static com.sun.tools.javac.code.Flags.BLOCK;
67106813Ssimokawaimport static com.sun.tools.javac.code.Flags.STATIC;
68106813Ssimokawaimport static com.sun.tools.javac.code.Kinds.*;
69106813Ssimokawaimport static com.sun.tools.javac.code.Kinds.Kind.*;
70106813Ssimokawaimport static com.sun.tools.javac.code.TypeTag.*;
71106813Ssimokawaimport static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
72106813Ssimokawaimport static com.sun.tools.javac.tree.JCTree.Tag.*;
73106813Ssimokawa
74120660Ssimokawa/** Helper class for name resolution, used mostly by the attribution phase.
75106813Ssimokawa *
76126080Sphk *  <p><b>This is NOT part of any supported API.
77111942Ssimokawa *  If you write code that depends on this, you do so at your own risk.
78126080Sphk *  This code and its internal interfaces are subject to change or
79111815Sphk *  deletion without notice.</b>
80111815Sphk */
81111815Sphkpublic class Resolve {
82111815Sphk    protected static final Context.Key<Resolve> resolveKey = new Context.Key<>();
83111815Sphk
84111815Sphk    Names names;
85111815Sphk    Log log;
86120660Ssimokawa    Symtab syms;
87111815Sphk    Attr attr;
88126080Sphk    DeferredAttr deferredAttr;
89111942Ssimokawa    Check chk;
90111942Ssimokawa    Infer infer;
91120660Ssimokawa    ClassFinder finder;
92118455Ssimokawa    Types types;
93111942Ssimokawa    JCDiagnostic.Factory diags;
94106813Ssimokawa    public final boolean allowMethodHandles;
95106813Ssimokawa    public final boolean allowFunctionalInterfaceMostSpecific;
96118293Ssimokawa    public final boolean checkVarargsAccessAfterResolution;
97118293Ssimokawa    private final boolean compactMethodDiags;
98118293Ssimokawa    final EnumSet<VerboseResolutionMode> verboseResolutionMode;
99118293Ssimokawa
100118293Ssimokawa    WriteableScope polymorphicSignatureScope;
101118293Ssimokawa
102106813Ssimokawa    protected Resolve(Context context) {
103118293Ssimokawa        context.put(resolveKey, this);
104118293Ssimokawa        syms = Symtab.instance(context);
105118293Ssimokawa
106118293Ssimokawa        varNotFound = new SymbolNotFoundError(ABSENT_VAR);
107118293Ssimokawa        methodNotFound = new SymbolNotFoundError(ABSENT_MTH);
108118293Ssimokawa        typeNotFound = new SymbolNotFoundError(ABSENT_TYP);
109118293Ssimokawa        referenceNotFound = new ReferenceLookupResult(methodNotFound, null);
110118293Ssimokawa
111118293Ssimokawa        names = Names.instance(context);
112118293Ssimokawa        log = Log.instance(context);
113118293Ssimokawa        attr = Attr.instance(context);
114118293Ssimokawa        deferredAttr = DeferredAttr.instance(context);
115118293Ssimokawa        chk = Check.instance(context);
116118293Ssimokawa        infer = Infer.instance(context);
117118293Ssimokawa        finder = ClassFinder.instance(context);
118118293Ssimokawa        types = Types.instance(context);
119118293Ssimokawa        diags = JCDiagnostic.Factory.instance(context);
120118293Ssimokawa        Source source = Source.instance(context);
121118293Ssimokawa        Options options = Options.instance(context);
122118293Ssimokawa        compactMethodDiags = options.isSet(Option.XDIAGS, "compact") ||
123118293Ssimokawa                options.isUnset(Option.XDIAGS) && options.isUnset("rawDiagnostics");
124118293Ssimokawa        verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
125118293Ssimokawa        Target target = Target.instance(context);
126118293Ssimokawa        allowMethodHandles = target.hasMethodHandles();
127118293Ssimokawa        allowFunctionalInterfaceMostSpecific = source.allowFunctionalInterfaceMostSpecific();
128118293Ssimokawa        checkVarargsAccessAfterResolution =
129118293Ssimokawa                source.allowPostApplicabilityVarargsAccessCheck();
130118293Ssimokawa        polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
131118293Ssimokawa
132118293Ssimokawa        inapplicableMethodException = new InapplicableMethodException(diags);
133118293Ssimokawa    }
134118293Ssimokawa
135118293Ssimokawa    /** error symbols, which are returned when resolution fails
136118293Ssimokawa     */
137118293Ssimokawa    private final SymbolNotFoundError varNotFound;
138118293Ssimokawa    private final SymbolNotFoundError methodNotFound;
139118293Ssimokawa    private final SymbolNotFoundError typeNotFound;
140118293Ssimokawa
141118293Ssimokawa    /** empty reference lookup result */
142118293Ssimokawa    private final ReferenceLookupResult referenceNotFound;
143118293Ssimokawa
144118293Ssimokawa    public static Resolve instance(Context context) {
145118293Ssimokawa        Resolve instance = context.get(resolveKey);
146118293Ssimokawa        if (instance == null)
147118293Ssimokawa            instance = new Resolve(context);
148118293Ssimokawa        return instance;
149118293Ssimokawa    }
150118293Ssimokawa
151118293Ssimokawa    private static Symbol bestOf(Symbol s1,
152118293Ssimokawa                                 Symbol s2) {
153118293Ssimokawa        return s1.kind.betterThan(s2.kind) ? s1 : s2;
154118293Ssimokawa    }
155118293Ssimokawa
156118293Ssimokawa    // <editor-fold defaultstate="collapsed" desc="Verbose resolution diagnostics support">
157118293Ssimokawa    enum VerboseResolutionMode {
158118293Ssimokawa        SUCCESS("success"),
159118293Ssimokawa        FAILURE("failure"),
160118293Ssimokawa        APPLICABLE("applicable"),
161118293Ssimokawa        INAPPLICABLE("inapplicable"),
162118293Ssimokawa        DEFERRED_INST("deferred-inference"),
163118293Ssimokawa        PREDEF("predef"),
164118293Ssimokawa        OBJECT_INIT("object-init"),
165118293Ssimokawa        INTERNAL("internal");
166118293Ssimokawa
167106813Ssimokawa        final String opt;
168106813Ssimokawa
169106813Ssimokawa        private VerboseResolutionMode(String opt) {
170106813Ssimokawa            this.opt = opt;
171122227Ssimokawa        }
172122227Ssimokawa
173122227Ssimokawa        static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) {
174118293Ssimokawa            String s = opts.get("verboseResolution");
175118293Ssimokawa            EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class);
176118293Ssimokawa            if (s == null) return res;
177118293Ssimokawa            if (s.contains("all")) {
178118455Ssimokawa                res = EnumSet.allOf(VerboseResolutionMode.class);
179118455Ssimokawa            }
180118455Ssimokawa            Collection<String> args = Arrays.asList(s.split(","));
181118455Ssimokawa            for (VerboseResolutionMode mode : values()) {
182118293Ssimokawa                if (args.contains(mode.opt)) {
183118293Ssimokawa                    res.add(mode);
184118293Ssimokawa                } else if (args.contains("-" + mode.opt)) {
185118455Ssimokawa                    res.remove(mode);
186118455Ssimokawa                }
187118293Ssimokawa            }
188118293Ssimokawa            return res;
189118293Ssimokawa        }
190106813Ssimokawa    }
191106813Ssimokawa
192106813Ssimokawa    void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site,
193106813Ssimokawa            List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) {
194106813Ssimokawa        boolean success = !bestSoFar.kind.isResolutionError();
195106813Ssimokawa
196106813Ssimokawa        if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) {
197118293Ssimokawa            return;
198118293Ssimokawa        } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) {
199106813Ssimokawa            return;
200106813Ssimokawa        }
201106813Ssimokawa
202106813Ssimokawa        if (bestSoFar.name == names.init &&
203106813Ssimokawa                bestSoFar.owner == syms.objectType.tsym &&
204106813Ssimokawa                !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) {
205106813Ssimokawa            return; //skip diags for Object constructor resolution
206106813Ssimokawa        } else if (site == syms.predefClass.type &&
207106813Ssimokawa                !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) {
208118293Ssimokawa            return; //skip spurious diags for predef symbols (i.e. operators)
209118293Ssimokawa        } else if (currentResolutionContext.internalResolution &&
210118293Ssimokawa                !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) {
211118293Ssimokawa            return;
212118293Ssimokawa        }
213118293Ssimokawa
214118293Ssimokawa        int pos = 0;
215118293Ssimokawa        int mostSpecificPos = -1;
216118293Ssimokawa        ListBuffer<JCDiagnostic> subDiags = new ListBuffer<>();
217118293Ssimokawa        for (Candidate c : currentResolutionContext.candidates) {
218118293Ssimokawa            if (currentResolutionContext.step != c.step ||
219118293Ssimokawa                    (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) ||
220118293Ssimokawa                    (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) {
221118293Ssimokawa                continue;
222118293Ssimokawa            } else {
223118293Ssimokawa                subDiags.append(c.isApplicable() ?
224118293Ssimokawa                        getVerboseApplicableCandidateDiag(pos, c.sym, c.mtype) :
225118293Ssimokawa                        getVerboseInapplicableCandidateDiag(pos, c.sym, c.details));
226118293Ssimokawa                if (c.sym == bestSoFar)
227118293Ssimokawa                    mostSpecificPos = pos;
228118293Ssimokawa                pos++;
229118293Ssimokawa            }
230118293Ssimokawa        }
231118293Ssimokawa        String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1";
232118293Ssimokawa        List<Type> argtypes2 = argtypes.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, bestSoFar, currentResolutionContext.step));
233118293Ssimokawa        JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name,
234118293Ssimokawa                site.tsym, mostSpecificPos, currentResolutionContext.step,
235118293Ssimokawa                methodArguments(argtypes2),
236118293Ssimokawa                methodArguments(typeargtypes));
237118293Ssimokawa        JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList());
238118293Ssimokawa        log.report(d);
239118293Ssimokawa    }
240118293Ssimokawa
241118293Ssimokawa    JCDiagnostic getVerboseApplicableCandidateDiag(int pos, Symbol sym, Type inst) {
242106813Ssimokawa        JCDiagnostic subDiag = null;
243118293Ssimokawa        if (sym.type.hasTag(FORALL)) {
244118293Ssimokawa            subDiag = diags.fragment("partial.inst.sig", inst);
245106813Ssimokawa        }
246118293Ssimokawa
247118293Ssimokawa        String key = subDiag == null ?
248118293Ssimokawa                "applicable.method.found" :
249118293Ssimokawa                "applicable.method.found.1";
250118293Ssimokawa
251118293Ssimokawa        return diags.fragment(key, pos, sym, subDiag);
252118293Ssimokawa    }
253118293Ssimokawa
254118293Ssimokawa    JCDiagnostic getVerboseInapplicableCandidateDiag(int pos, Symbol sym, JCDiagnostic subDiag) {
255118293Ssimokawa        return diags.fragment("not.applicable.method.found", pos, sym, subDiag);
256118293Ssimokawa    }
257106813Ssimokawa    // </editor-fold>
258118293Ssimokawa
259118293Ssimokawa/* ************************************************************************
260106813Ssimokawa * Identifier resolution
261106813Ssimokawa *************************************************************************/
262106813Ssimokawa
263106813Ssimokawa    /** An environment is "static" if its static level is greater than
264106813Ssimokawa     *  the one of its outer environment
265106813Ssimokawa     */
266106813Ssimokawa    protected static boolean isStatic(Env<AttrContext> env) {
267106813Ssimokawa        return env.outer != null && env.info.staticLevel > env.outer.info.staticLevel;
268106813Ssimokawa    }
269106813Ssimokawa
270106813Ssimokawa    /** An environment is an "initializer" if it is a constructor or
271106813Ssimokawa     *  an instance initializer.
272106813Ssimokawa     */
273106813Ssimokawa    static boolean isInitializer(Env<AttrContext> env) {
274106813Ssimokawa        Symbol owner = env.info.scope.owner;
275106813Ssimokawa        return owner.isConstructor() ||
276106813Ssimokawa            owner.owner.kind == TYP &&
277106813Ssimokawa            (owner.kind == VAR ||
278120660Ssimokawa             owner.kind == MTH && (owner.flags() & BLOCK) != 0) &&
279106813Ssimokawa            (owner.flags() & STATIC) == 0;
280106813Ssimokawa    }
281106813Ssimokawa
282118293Ssimokawa    /** Is class accessible in given evironment?
283118293Ssimokawa     *  @param env    The current environment.
284118293Ssimokawa     *  @param c      The class whose accessibility is checked.
285106813Ssimokawa     */
286106813Ssimokawa    public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) {
287106813Ssimokawa        return isAccessible(env, c, false);
288113584Ssimokawa    }
289109988Ssimokawa
290106813Ssimokawa    public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) {
291109988Ssimokawa
292106813Ssimokawa        /* 15.9.5.1: Note that it is possible for the signature of the anonymous constructor
293106813Ssimokawa           to refer to an inaccessible type
294106813Ssimokawa        */
295106813Ssimokawa        if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0)
296106813Ssimokawa            return true;
297106813Ssimokawa
298109988Ssimokawa        boolean isAccessible = false;
299109988Ssimokawa        switch ((short)(c.flags() & AccessFlags)) {
300109988Ssimokawa            case PRIVATE:
301106813Ssimokawa                isAccessible =
302106813Ssimokawa                    env.enclClass.sym.outermostClass() ==
303111748Sdes                    c.owner.outermostClass();
304109988Ssimokawa                break;
305109988Ssimokawa            case 0:
306109988Ssimokawa                isAccessible =
307109988Ssimokawa                    env.toplevel.packge == c.owner // fast special case
308106813Ssimokawa                    ||
309109988Ssimokawa                    env.toplevel.packge == c.packge();
310109988Ssimokawa                break;
311120660Ssimokawa            default: // error recovery
312113584Ssimokawa            case PUBLIC:
313106813Ssimokawa                isAccessible = true;
314106813Ssimokawa                break;
315106813Ssimokawa            case PROTECTED:
316106813Ssimokawa                isAccessible =
317120660Ssimokawa                    env.toplevel.packge == c.owner // fast special case
318120660Ssimokawa                    ||
319106813Ssimokawa                    env.toplevel.packge == c.packge()
320120660Ssimokawa                    ||
321120660Ssimokawa                    isInnerSubClass(env.enclClass.sym, c.owner);
322113584Ssimokawa                break;
323120660Ssimokawa        }
324106813Ssimokawa        return (checkInner == false || c.type.getEnclosingType() == Type.noType) ?
325109988Ssimokawa            isAccessible :
326109988Ssimokawa            isAccessible && isAccessible(env, c.type.getEnclosingType(), checkInner);
327113584Ssimokawa    }
328113584Ssimokawa    //where
329106813Ssimokawa        /** Is given class a subclass of given base class, or an inner class
330106813Ssimokawa         *  of a subclass?
331113584Ssimokawa         *  Return null if no such class exists.
332106813Ssimokawa         *  @param c     The class which is the subclass or is contained in it.
333106813Ssimokawa         *  @param base  The base class
334106813Ssimokawa         */
335109988Ssimokawa        private boolean isInnerSubClass(ClassSymbol c, Symbol base) {
336113584Ssimokawa            while (c != null && !c.isSubClass(base, types)) {
337106813Ssimokawa                c = c.owner.enclClass();
338106813Ssimokawa            }
339106813Ssimokawa            return c != null;
340106813Ssimokawa        }
341106813Ssimokawa
342118293Ssimokawa    boolean isAccessible(Env<AttrContext> env, Type t) {
343106813Ssimokawa        return isAccessible(env, t, false);
344106813Ssimokawa    }
345109988Ssimokawa
346109988Ssimokawa    boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) {
347109988Ssimokawa        return (t.hasTag(ARRAY))
348109988Ssimokawa            ? isAccessible(env, types.cvarUpperBound(types.elemtype(t)))
349106813Ssimokawa            : isAccessible(env, t.tsym, checkInner);
350106813Ssimokawa    }
351106813Ssimokawa
352106813Ssimokawa    /** Is symbol accessible as a member of given type in given environment?
353106813Ssimokawa     *  @param env    The current environment.
354106813Ssimokawa     *  @param site   The type of which the tested symbol is regarded
355106813Ssimokawa     *                as a member.
356106813Ssimokawa     *  @param sym    The symbol.
357106813Ssimokawa     */
358106813Ssimokawa    public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) {
359106813Ssimokawa        return isAccessible(env, site, sym, false);
360106813Ssimokawa    }
361106813Ssimokawa    public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) {
362106813Ssimokawa        if (sym.name == names.init && sym.owner != site.tsym) return false;
363106813Ssimokawa
364106813Ssimokawa        /* 15.9.5.1: Note that it is possible for the signature of the anonymous constructor
365120660Ssimokawa           to refer to an inaccessible type
366106813Ssimokawa        */
367106813Ssimokawa        if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0)
368106813Ssimokawa            return true;
369118293Ssimokawa
370118293Ssimokawa        switch ((short)(sym.flags() & AccessFlags)) {
371118293Ssimokawa        case PRIVATE:
372106813Ssimokawa            return
373113802Ssimokawa                (env.enclClass.sym == sym.owner // fast special case
374113802Ssimokawa                 ||
375113802Ssimokawa                 env.enclClass.sym.outermostClass() ==
376106813Ssimokawa                 sym.owner.outermostClass())
377113802Ssimokawa                &&
378106813Ssimokawa                sym.isInheritedIn(site.tsym, types);
379113802Ssimokawa        case 0:
380113802Ssimokawa            return
381113802Ssimokawa                (env.toplevel.packge == sym.owner.owner // fast special case
382118293Ssimokawa                 ||
383113802Ssimokawa                 env.toplevel.packge == sym.packge())
384113802Ssimokawa                &&
385113802Ssimokawa                isAccessible(env, site, checkInner)
386113802Ssimokawa                &&
387113802Ssimokawa                sym.isInheritedIn(site.tsym, types)
388109988Ssimokawa                &&
389113802Ssimokawa                notOverriddenIn(site, sym);
390113802Ssimokawa        case PROTECTED:
391106813Ssimokawa            return
392106813Ssimokawa                (env.toplevel.packge == sym.owner.owner // fast special case
393106813Ssimokawa                 ||
394113802Ssimokawa                 env.toplevel.packge == sym.packge()
395113802Ssimokawa                 ||
396113802Ssimokawa                 isProtectedAccessible(sym, env.enclClass.sym, site)
397113802Ssimokawa                 ||
398113802Ssimokawa                 // OK to select instance method or field from 'super' or type name
399113802Ssimokawa                 // (but type names should be disallowed elsewhere!)
400113802Ssimokawa                 env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP)
401113802Ssimokawa                &&
402113802Ssimokawa                isAccessible(env, site, checkInner)
403113802Ssimokawa                &&
404113802Ssimokawa                notOverriddenIn(site, sym);
405118293Ssimokawa        default: // this case includes erroneous combinations as well
406113802Ssimokawa            return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym);
407113802Ssimokawa        }
408113802Ssimokawa    }
409113802Ssimokawa    //where
410113802Ssimokawa    /* `sym' is accessible only if not overridden by
411113802Ssimokawa     * another symbol which is a member of `site'
412106813Ssimokawa     * (because, if it is overridden, `sym' is not strictly
413106813Ssimokawa     * speaking a member of `site'). A polymorphic signature method
414106813Ssimokawa     * cannot be overridden (e.g. MH.invokeExact(Object[])).
415106813Ssimokawa     */
416106813Ssimokawa    private boolean notOverriddenIn(Type site, Symbol sym) {
417106813Ssimokawa        if (sym.kind != MTH || sym.isConstructor() || sym.isStatic())
418106813Ssimokawa            return true;
419106813Ssimokawa        else {
420118293Ssimokawa            Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true);
421118293Ssimokawa            return (s2 == null || s2 == sym || sym.owner == s2.owner ||
422106813Ssimokawa                    !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
423113584Ssimokawa        }
424106813Ssimokawa    }
425106813Ssimokawa    //where
426106813Ssimokawa        /** Is given protected symbol accessible if it is selected from given site
427106813Ssimokawa         *  and the selection takes place in given class?
428106813Ssimokawa         *  @param sym     The symbol with protected access
429109814Ssimokawa         *  @param c       The class where the access takes place
430117473Ssimokawa         *  @site          The type of the qualifier
431106813Ssimokawa         */
432106813Ssimokawa        private
433106813Ssimokawa        boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) {
434106813Ssimokawa            Type newSite = site.hasTag(TYPEVAR) ? site.getUpperBound() : site;
435106813Ssimokawa            while (c != null &&
436106813Ssimokawa                   !(c.isSubClass(sym.owner, types) &&
437106813Ssimokawa                     (c.flags() & INTERFACE) == 0 &&
438106813Ssimokawa                     // In JLS 2e 6.6.2.1, the subclass restriction applies
439106813Ssimokawa                     // only to instance fields and methods -- types are excluded
440106813Ssimokawa                     // regardless of whether they are declared 'static' or not.
441106813Ssimokawa                     ((sym.flags() & STATIC) != 0 || sym.kind == TYP || newSite.tsym.isSubClass(c, types))))
442106813Ssimokawa                c = c.owner.enclClass();
443106813Ssimokawa            return c != null;
444106813Ssimokawa        }
445118293Ssimokawa
446118293Ssimokawa    /**
447118293Ssimokawa     * Performs a recursive scan of a type looking for accessibility problems
448118293Ssimokawa     * from current attribution environment
449118293Ssimokawa     */
450118293Ssimokawa    void checkAccessibleType(Env<AttrContext> env, Type t) {
451106813Ssimokawa        accessibilityChecker.visit(t, env);
452106813Ssimokawa    }
453118293Ssimokawa
454118293Ssimokawa    /**
455118293Ssimokawa     * Accessibility type-visitor
456118293Ssimokawa     */
457118293Ssimokawa    Types.SimpleVisitor<Void, Env<AttrContext>> accessibilityChecker =
458118293Ssimokawa            new Types.SimpleVisitor<Void, Env<AttrContext>>() {
459118293Ssimokawa
460118293Ssimokawa        void visit(List<Type> ts, Env<AttrContext> env) {
461118293Ssimokawa            for (Type t : ts) {
462118293Ssimokawa                visit(t, env);
463118293Ssimokawa            }
464118293Ssimokawa        }
465118293Ssimokawa
466118293Ssimokawa        public Void visitType(Type t, Env<AttrContext> env) {
467118293Ssimokawa            return null;
468118293Ssimokawa        }
469118293Ssimokawa
470118293Ssimokawa        @Override
471118293Ssimokawa        public Void visitArrayType(ArrayType t, Env<AttrContext> env) {
472106813Ssimokawa            visit(t.elemtype, env);
473106813Ssimokawa            return null;
474118293Ssimokawa        }
475118293Ssimokawa
476118293Ssimokawa        @Override
477118293Ssimokawa        public Void visitClassType(ClassType t, Env<AttrContext> env) {
478118293Ssimokawa            visit(t.getTypeArguments(), env);
479106813Ssimokawa            if (!isAccessible(env, t, true)) {
480106813Ssimokawa                accessBase(new AccessError(t.tsym), env.tree.pos(), env.enclClass.sym, t, t.tsym.name, true);
481118293Ssimokawa            }
482118293Ssimokawa            return null;
483118293Ssimokawa        }
484118293Ssimokawa
485118293Ssimokawa        @Override
486118293Ssimokawa        public Void visitWildcardType(WildcardType t, Env<AttrContext> env) {
487118293Ssimokawa            visit(t.type, env);
488118293Ssimokawa            return null;
489118293Ssimokawa        }
490118293Ssimokawa
491118293Ssimokawa        @Override
492118293Ssimokawa        public Void visitMethodType(MethodType t, Env<AttrContext> env) {
493118293Ssimokawa            visit(t.getParameterTypes(), env);
494118293Ssimokawa            visit(t.getReturnType(), env);
495118293Ssimokawa            visit(t.getThrownTypes(), env);
496118293Ssimokawa            return null;
497118293Ssimokawa        }
498118293Ssimokawa    };
499118293Ssimokawa
500118293Ssimokawa    /** Try to instantiate the type of a method so that it fits
501106813Ssimokawa     *  given type arguments and argument types. If successful, return
502106813Ssimokawa     *  the method's instantiated type, else return null.
503118293Ssimokawa     *  The instantiation will take into account an additional leading
504118293Ssimokawa     *  formal parameter if the method is an instance method seen as a member
505118293Ssimokawa     *  of an under determined site. In this case, we treat site as an additional
506118293Ssimokawa     *  parameter and the parameters of the class containing the method as
507118293Ssimokawa     *  additional type variables that get instantiated.
508106813Ssimokawa     *
509106813Ssimokawa     *  @param env         The current environment
510118293Ssimokawa     *  @param site        The type of which the method is a member.
511106813Ssimokawa     *  @param m           The method symbol.
512106813Ssimokawa     *  @param argtypes    The invocation's given value arguments.
513118293Ssimokawa     *  @param typeargtypes    The invocation's given type arguments.
514118293Ssimokawa     *  @param allowBoxing Allow boxing conversions of arguments.
515118293Ssimokawa     *  @param useVarargs Box trailing arguments into an array for varargs.
516118293Ssimokawa     */
517118293Ssimokawa    Type rawInstantiate(Env<AttrContext> env,
518118293Ssimokawa                        Type site,
519118293Ssimokawa                        Symbol m,
520118293Ssimokawa                        ResultInfo resultInfo,
521118293Ssimokawa                        List<Type> argtypes,
522118293Ssimokawa                        List<Type> typeargtypes,
523118293Ssimokawa                        boolean allowBoxing,
524118293Ssimokawa                        boolean useVarargs,
525106813Ssimokawa                        Warner warn) throws Infer.InferenceException {
526106813Ssimokawa        Type mt = types.memberType(site, m);
527120660Ssimokawa        // tvars is the list of formal type variables for which type arguments
528120660Ssimokawa        // need to inferred.
529121466Ssimokawa        List<Type> tvars = List.nil();
530120660Ssimokawa        if (typeargtypes == null) typeargtypes = List.nil();
531106813Ssimokawa        if (!mt.hasTag(FORALL) && typeargtypes.nonEmpty()) {
532121466Ssimokawa            // This is not a polymorphic method, but typeargs are supplied
533121466Ssimokawa            // which is fine, see JLS 15.12.2.1
534121466Ssimokawa        } else if (mt.hasTag(FORALL) && typeargtypes.nonEmpty()) {
535121466Ssimokawa            ForAll pmt = (ForAll) mt;
536121466Ssimokawa            if (typeargtypes.length() != pmt.tvars.length())
537121466Ssimokawa                throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
538121466Ssimokawa            // Check type arguments are within bounds
539121466Ssimokawa            List<Type> formals = pmt.tvars;
540121466Ssimokawa            List<Type> actuals = typeargtypes;
541106813Ssimokawa            while (formals.nonEmpty() && actuals.nonEmpty()) {
542106813Ssimokawa                List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head),
543106813Ssimokawa                                                pmt.tvars, typeargtypes);
544106813Ssimokawa                for (; bounds.nonEmpty(); bounds = bounds.tail) {
545110072Ssimokawa                    if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn))
546110582Ssimokawa                        throw inapplicableMethodException.setMessage("explicit.param.do.not.conform.to.bounds",actuals.head, bounds);
547106813Ssimokawa                }
548108782Ssimokawa                formals = formals.tail;
549108782Ssimokawa                actuals = actuals.tail;
550106813Ssimokawa            }
551121466Ssimokawa            mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes);
552106813Ssimokawa        } else if (mt.hasTag(FORALL)) {
553120660Ssimokawa            ForAll pmt = (ForAll) mt;
554106813Ssimokawa            List<Type> tvars1 = types.newInstances(pmt.tvars);
555106813Ssimokawa            tvars = tvars.appendList(tvars1);
556106813Ssimokawa            mt = types.subst(pmt.qtype, pmt.tvars, tvars1);
557106813Ssimokawa        }
558106813Ssimokawa
559106813Ssimokawa        // find out whether we need to go the slow route via infer
560106813Ssimokawa        boolean instNeeded = tvars.tail != null; /*inlined: tvars.nonEmpty()*/
561106813Ssimokawa        for (List<Type> l = argtypes;
562121466Ssimokawa             l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
563120660Ssimokawa             l = l.tail) {
564121466Ssimokawa            if (l.head.hasTag(FORALL)) instNeeded = true;
565120660Ssimokawa        }
566121466Ssimokawa
567121466Ssimokawa        if (instNeeded) {
568106813Ssimokawa            return infer.instantiateMethod(env,
569121466Ssimokawa                                    tvars,
570121466Ssimokawa                                    (MethodType)mt,
571121466Ssimokawa                                    resultInfo,
572121466Ssimokawa                                    (MethodSymbol)m,
573121466Ssimokawa                                    argtypes,
574121466Ssimokawa                                    allowBoxing,
575121466Ssimokawa                                    useVarargs,
576121466Ssimokawa                                    currentResolutionContext,
577106813Ssimokawa                                    warn);
578121466Ssimokawa        }
579121466Ssimokawa
580121466Ssimokawa        DeferredAttr.DeferredAttrContext dc = currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn);
581121466Ssimokawa        currentResolutionContext.methodCheck.argumentsAcceptable(env, dc,
582121466Ssimokawa                                argtypes, mt.getParameterTypes(), warn);
583121466Ssimokawa        dc.complete();
584121466Ssimokawa        return mt;
585121466Ssimokawa    }
586121466Ssimokawa
587121466Ssimokawa    Type checkMethod(Env<AttrContext> env,
588121466Ssimokawa                     Type site,
589121466Ssimokawa                     Symbol m,
590121466Ssimokawa                     ResultInfo resultInfo,
591120660Ssimokawa                     List<Type> argtypes,
592106813Ssimokawa                     List<Type> typeargtypes,
593120660Ssimokawa                     Warner warn) {
594106813Ssimokawa        MethodResolutionContext prevContext = currentResolutionContext;
595106813Ssimokawa        try {
596106813Ssimokawa            currentResolutionContext = new MethodResolutionContext();
597106813Ssimokawa            currentResolutionContext.attrMode = (resultInfo.pt == Infer.anyPoly) ?
598106813Ssimokawa                    AttrMode.SPECULATIVE : DeferredAttr.AttrMode.CHECK;
599106813Ssimokawa            if (env.tree.hasTag(JCTree.Tag.REFERENCE)) {
600106813Ssimokawa                //method/constructor references need special check class
601106813Ssimokawa                //to handle inference variables in 'argtypes' (might happen
602106813Ssimokawa                //during an unsticking round)
603106813Ssimokawa                currentResolutionContext.methodCheck =
604106813Ssimokawa                        new MethodReferenceCheck(resultInfo.checkContext.inferenceContext());
605118293Ssimokawa            }
606110195Ssimokawa            MethodResolutionPhase step = currentResolutionContext.step = env.info.pendingResolutionPhase;
607106813Ssimokawa            return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
608106813Ssimokawa                    step.isBoxingRequired(), step.isVarargsRequired(), warn);
609106813Ssimokawa        }
610106813Ssimokawa        finally {
611106813Ssimokawa            currentResolutionContext = prevContext;
612106813Ssimokawa        }
613106813Ssimokawa    }
614106813Ssimokawa
615106813Ssimokawa    /** Same but returns null instead throwing a NoInstanceException
616106813Ssimokawa     */
617110195Ssimokawa    Type instantiate(Env<AttrContext> env,
618106813Ssimokawa                     Type site,
619106813Ssimokawa                     Symbol m,
620106813Ssimokawa                     ResultInfo resultInfo,
621106813Ssimokawa                     List<Type> argtypes,
622120660Ssimokawa                     List<Type> typeargtypes,
623120660Ssimokawa                     boolean allowBoxing,
624120660Ssimokawa                     boolean useVarargs,
625118293Ssimokawa                     Warner warn) {
626118293Ssimokawa        try {
627113584Ssimokawa            return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
628106813Ssimokawa                                  allowBoxing, useVarargs, warn);
629120660Ssimokawa        } catch (InapplicableMethodException ex) {
630110269Ssimokawa            return null;
631106813Ssimokawa        }
632124836Ssimokawa    }
633124836Ssimokawa
634106813Ssimokawa    /**
635106813Ssimokawa     * This interface defines an entry point that should be used to perform a
636106813Ssimokawa     * method check. A method check usually consist in determining as to whether
637113584Ssimokawa     * a set of types (actuals) is compatible with another set of types (formals).
638113584Ssimokawa     * Since the notion of compatibility can vary depending on the circumstances,
639113584Ssimokawa     * this interfaces allows to easily add new pluggable method check routines.
640113584Ssimokawa     */
641113584Ssimokawa    interface MethodCheck {
642106813Ssimokawa        /**
643106813Ssimokawa         * Main method check routine. A method check usually consist in determining
644106813Ssimokawa         * as to whether a set of types (actuals) is compatible with another set of
645109814Ssimokawa         * types (formals). If an incompatibility is found, an unchecked exception
646109814Ssimokawa         * is assumed to be thrown.
647109814Ssimokawa         */
648109814Ssimokawa        void argumentsAcceptable(Env<AttrContext> env,
649109814Ssimokawa                                DeferredAttrContext deferredAttrContext,
650109814Ssimokawa                                List<Type> argtypes,
651109814Ssimokawa                                List<Type> formals,
652110193Ssimokawa                                Warner warn);
653109814Ssimokawa
654109814Ssimokawa        /**
655109814Ssimokawa         * Retrieve the method check object that will be used during a
656109814Ssimokawa         * most specific check.
657109814Ssimokawa         */
658109814Ssimokawa        MethodCheck mostSpecificCheck(List<Type> actuals);
659109814Ssimokawa    }
660106813Ssimokawa
661106813Ssimokawa    /**
662106813Ssimokawa     * Helper enum defining all method check diagnostics (used by resolveMethodCheck).
663106813Ssimokawa     */
664109814Ssimokawa    enum MethodCheckDiag {
665106813Ssimokawa        /**
666106813Ssimokawa         * Actuals and formals differs in length.
667106813Ssimokawa         */
668106813Ssimokawa        ARITY_MISMATCH("arg.length.mismatch", "infer.arg.length.mismatch"),
669106813Ssimokawa        /**
670106813Ssimokawa         * An actual is incompatible with a formal.
671110193Ssimokawa         */
672110193Ssimokawa        ARG_MISMATCH("no.conforming.assignment.exists", "infer.no.conforming.assignment.exists"),
673106813Ssimokawa        /**
674106813Ssimokawa         * An actual is incompatible with the varargs element type.
675117473Ssimokawa         */
676117473Ssimokawa        VARARG_MISMATCH("varargs.argument.mismatch", "infer.varargs.argument.mismatch"),
677117473Ssimokawa        /**
678117473Ssimokawa         * The varargs element type is inaccessible.
679117473Ssimokawa         */
680117473Ssimokawa        INACCESSIBLE_VARARGS("inaccessible.varargs.type", "inaccessible.varargs.type");
681117473Ssimokawa
682117473Ssimokawa        final String basicKey;
683117473Ssimokawa        final String inferKey;
684117473Ssimokawa
685117473Ssimokawa        MethodCheckDiag(String basicKey, String inferKey) {
686117473Ssimokawa            this.basicKey = basicKey;
687117473Ssimokawa            this.inferKey = inferKey;
688117473Ssimokawa        }
689117473Ssimokawa
690117473Ssimokawa        String regex() {
691117473Ssimokawa            return String.format("([a-z]*\\.)*(%s|%s)", basicKey, inferKey);
692106813Ssimokawa        }
693106813Ssimokawa    }
694106813Ssimokawa
695106813Ssimokawa    /**
696106813Ssimokawa     * Dummy method check object. All methods are deemed applicable, regardless
697117473Ssimokawa     * of their formal parameter types.
698117473Ssimokawa     */
699117473Ssimokawa    MethodCheck nilMethodCheck = new MethodCheck() {
700117473Ssimokawa        public void argumentsAcceptable(Env<AttrContext> env, DeferredAttrContext deferredAttrContext, List<Type> argtypes, List<Type> formals, Warner warn) {
701106813Ssimokawa            //do nothing - method always applicable regardless of actuals
702106813Ssimokawa        }
703106813Ssimokawa
704106813Ssimokawa        public MethodCheck mostSpecificCheck(List<Type> actuals) {
705106813Ssimokawa            return this;
706106813Ssimokawa        }
707106813Ssimokawa    };
708106813Ssimokawa
709106813Ssimokawa    /**
710106813Ssimokawa     * Base class for 'real' method checks. The class defines the logic for
711118293Ssimokawa     * iterating through formals and actuals and provides and entry point
712118293Ssimokawa     * that can be used by subclasses in order to define the actual check logic.
713106813Ssimokawa     */
714106813Ssimokawa    abstract class AbstractMethodCheck implements MethodCheck {
715106813Ssimokawa        @Override
716106813Ssimokawa        public void argumentsAcceptable(final Env<AttrContext> env,
717106813Ssimokawa                                    DeferredAttrContext deferredAttrContext,
718106813Ssimokawa                                    List<Type> argtypes,
719106813Ssimokawa                                    List<Type> formals,
720106813Ssimokawa                                    Warner warn) {
721118293Ssimokawa            //should we expand formals?
722106813Ssimokawa            boolean useVarargs = deferredAttrContext.phase.isVarargsRequired();
723106813Ssimokawa            JCTree callTree = treeForDiagnostics(env);
724106813Ssimokawa            List<JCExpression> trees = TreeInfo.args(callTree);
725118293Ssimokawa
726106813Ssimokawa            //inference context used during this method check
727106813Ssimokawa            InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
728118293Ssimokawa
729106813Ssimokawa            Type varargsFormal = useVarargs ? formals.last() : null;
730106813Ssimokawa
731106813Ssimokawa            if (varargsFormal == null &&
732106813Ssimokawa                    argtypes.size() != formals.size()) {
733106813Ssimokawa                reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
734106813Ssimokawa            }
735106813Ssimokawa
736106813Ssimokawa            while (argtypes.nonEmpty() && formals.head != varargsFormal) {
737106813Ssimokawa                DiagnosticPosition pos = trees != null ? trees.head : null;
738106813Ssimokawa                checkArg(pos, false, argtypes.head, formals.head, deferredAttrContext, warn);
739106813Ssimokawa                argtypes = argtypes.tail;
740113584Ssimokawa                formals = formals.tail;
741111615Ssimokawa                trees = trees != null ? trees.tail : trees;
742111615Ssimokawa            }
743113584Ssimokawa
744111615Ssimokawa            if (formals.head != varargsFormal) {
745106813Ssimokawa                reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
746118455Ssimokawa            }
747106813Ssimokawa
748106813Ssimokawa            if (useVarargs) {
749106813Ssimokawa                //note: if applicability check is triggered by most specific test,
750113584Ssimokawa                //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
751111615Ssimokawa                final Type elt = types.elemtype(varargsFormal);
752111615Ssimokawa                while (argtypes.nonEmpty()) {
753111462Smux                    DiagnosticPosition pos = trees != null ? trees.head : null;
754111615Ssimokawa                    checkArg(pos, true, argtypes.head, elt, deferredAttrContext, warn);
755106813Ssimokawa                    argtypes = argtypes.tail;
756118455Ssimokawa                    trees = trees != null ? trees.tail : trees;
757106813Ssimokawa                }
758106813Ssimokawa            }
759106813Ssimokawa        }
760118455Ssimokawa
761120660Ssimokawa            // where
762120660Ssimokawa            private JCTree treeForDiagnostics(Env<AttrContext> env) {
763120660Ssimokawa                return env.info.preferredTreeForDiagnostics != null ? env.info.preferredTreeForDiagnostics : env.tree;
764120660Ssimokawa            }
765120660Ssimokawa
766120660Ssimokawa        /**
767120660Ssimokawa         * Does the actual argument conforms to the corresponding formal?
768120660Ssimokawa         */
769120660Ssimokawa        abstract void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn);
770120660Ssimokawa
771120660Ssimokawa        protected void reportMC(DiagnosticPosition pos, MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) {
772120660Ssimokawa            boolean inferDiag = inferenceContext != infer.emptyContext;
773120660Ssimokawa            InapplicableMethodException ex = inferDiag ?
774120660Ssimokawa                    infer.inferenceException : inapplicableMethodException;
775120660Ssimokawa            if (inferDiag && (!diag.inferKey.equals(diag.basicKey))) {
776120660Ssimokawa                Object[] args2 = new Object[args.length + 1];
777120660Ssimokawa                System.arraycopy(args, 0, args2, 1, args.length);
778118455Ssimokawa                args2[0] = inferenceContext.inferenceVars();
779118455Ssimokawa                args = args2;
780118455Ssimokawa            }
781118455Ssimokawa            String key = inferDiag ? diag.inferKey : diag.basicKey;
782118455Ssimokawa            throw ex.setMessage(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args));
783118455Ssimokawa        }
784118455Ssimokawa
785118455Ssimokawa        public MethodCheck mostSpecificCheck(List<Type> actuals) {
786118455Ssimokawa            return nilMethodCheck;
787118455Ssimokawa        }
788118455Ssimokawa
789118455Ssimokawa    }
790118455Ssimokawa
791118455Ssimokawa    /**
792118455Ssimokawa     * Arity-based method check. A method is applicable if the number of actuals
793118455Ssimokawa     * supplied conforms to the method signature.
794118455Ssimokawa     */
795118455Ssimokawa    MethodCheck arityMethodCheck = new AbstractMethodCheck() {
796118455Ssimokawa        @Override
797118455Ssimokawa        void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
798118455Ssimokawa            //do nothing - actual always compatible to formals
799118455Ssimokawa        }
800118455Ssimokawa
801118455Ssimokawa        @Override
802118455Ssimokawa        public String toString() {
803118455Ssimokawa            return "arityMethodCheck";
804118455Ssimokawa        }
805118455Ssimokawa    };
806118455Ssimokawa
807118455Ssimokawa    List<Type> dummyArgs(int length) {
808118455Ssimokawa        ListBuffer<Type> buf = new ListBuffer<>();
809118455Ssimokawa        for (int i = 0 ; i < length ; i++) {
810118455Ssimokawa            buf.append(Type.noType);
811118455Ssimokawa        }
812118455Ssimokawa        return buf.toList();
813118455Ssimokawa    }
814118455Ssimokawa
815118455Ssimokawa    /**
816118455Ssimokawa     * Main method applicability routine. Given a list of actual types A,
817118455Ssimokawa     * a list of formal types F, determines whether the types in A are
818118455Ssimokawa     * compatible (by method invocation conversion) with the types in F.
819118455Ssimokawa     *
820118455Ssimokawa     * Since this routine is shared between overload resolution and method
821118455Ssimokawa     * type-inference, a (possibly empty) inference context is used to convert
822118455Ssimokawa     * formal types to the corresponding 'undet' form ahead of a compatibility
823118455Ssimokawa     * check so that constraints can be propagated and collected.
824118455Ssimokawa     *
825118455Ssimokawa     * Moreover, if one or more types in A is a deferred type, this routine uses
826118455Ssimokawa     * DeferredAttr in order to perform deferred attribution. If one or more actual
827118455Ssimokawa     * deferred types are stuck, they are placed in a queue and revisited later
828118455Ssimokawa     * after the remainder of the arguments have been seen. If this is not sufficient
829118455Ssimokawa     * to 'unstuck' the argument, a cyclic inference error is called out.
830118455Ssimokawa     *
831118455Ssimokawa     * A method check handler (see above) is used in order to report errors.
832118455Ssimokawa     */
833120624Ssimokawa    MethodCheck resolveMethodCheck = new AbstractMethodCheck() {
834118455Ssimokawa
835118455Ssimokawa        @Override
836118455Ssimokawa        void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
837118455Ssimokawa            ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn);
838118455Ssimokawa            mresult.check(pos, actual);
839118455Ssimokawa        }
840118455Ssimokawa
841118455Ssimokawa        @Override
842118455Ssimokawa        public void argumentsAcceptable(final Env<AttrContext> env,
843118455Ssimokawa                                    DeferredAttrContext deferredAttrContext,
844118455Ssimokawa                                    List<Type> argtypes,
845118455Ssimokawa                                    List<Type> formals,
846118455Ssimokawa                                    Warner warn) {
847118455Ssimokawa            super.argumentsAcceptable(env, deferredAttrContext, argtypes, formals, warn);
848118455Ssimokawa            // should we check varargs element type accessibility?
849118455Ssimokawa            if (deferredAttrContext.phase.isVarargsRequired()) {
850118455Ssimokawa                if (deferredAttrContext.mode == AttrMode.CHECK || !checkVarargsAccessAfterResolution) {
851118455Ssimokawa                    varargsAccessible(env, types.elemtype(formals.last()), deferredAttrContext.inferenceContext);
852118455Ssimokawa                }
853118455Ssimokawa            }
854118455Ssimokawa        }
855118455Ssimokawa
856118455Ssimokawa        /**
857118455Ssimokawa         * Test that the runtime array element type corresponding to 't' is accessible.  't' should be the
858118455Ssimokawa         * varargs element type of either the method invocation type signature (after inference completes)
859118455Ssimokawa         * or the method declaration signature (before inference completes).
860118455Ssimokawa         */
861        private void varargsAccessible(final Env<AttrContext> env, final Type t, final InferenceContext inferenceContext) {
862            if (inferenceContext.free(t)) {
863                inferenceContext.addFreeTypeListener(List.of(t), new FreeTypeListener() {
864                    @Override
865                    public void typesInferred(InferenceContext inferenceContext) {
866                        varargsAccessible(env, inferenceContext.asInstType(t), inferenceContext);
867                    }
868                });
869            } else {
870                if (!isAccessible(env, types.erasure(t))) {
871                    Symbol location = env.enclClass.sym;
872                    reportMC(env.tree, MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location);
873                }
874            }
875        }
876
877        private ResultInfo methodCheckResult(final boolean varargsCheck, Type to,
878                final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) {
879            CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) {
880                MethodCheckDiag methodDiag = varargsCheck ?
881                                 MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH;
882
883                @Override
884                public void report(DiagnosticPosition pos, JCDiagnostic details) {
885                    reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details);
886                }
887            };
888            return new MethodResultInfo(to, checkContext);
889        }
890
891        @Override
892        public MethodCheck mostSpecificCheck(List<Type> actuals) {
893            return new MostSpecificCheck(actuals);
894        }
895
896        @Override
897        public String toString() {
898            return "resolveMethodCheck";
899        }
900    };
901
902    /**
903     * This class handles method reference applicability checks; since during
904     * these checks it's sometime possible to have inference variables on
905     * the actual argument types list, the method applicability check must be
906     * extended so that inference variables are 'opened' as needed.
907     */
908    class MethodReferenceCheck extends AbstractMethodCheck {
909
910        InferenceContext pendingInferenceContext;
911
912        MethodReferenceCheck(InferenceContext pendingInferenceContext) {
913            this.pendingInferenceContext = pendingInferenceContext;
914        }
915
916        @Override
917        void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
918            ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn);
919            mresult.check(pos, actual);
920        }
921
922        private ResultInfo methodCheckResult(final boolean varargsCheck, Type to,
923                final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) {
924            CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) {
925                MethodCheckDiag methodDiag = varargsCheck ?
926                                 MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH;
927
928                @Override
929                public boolean compatible(Type found, Type req, Warner warn) {
930                    found = pendingInferenceContext.asUndetVar(found);
931                    if (found.hasTag(UNDETVAR) && req.isPrimitive()) {
932                        req = types.boxedClass(req).type;
933                    }
934                    return super.compatible(found, req, warn);
935                }
936
937                @Override
938                public void report(DiagnosticPosition pos, JCDiagnostic details) {
939                    reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details);
940                }
941            };
942            return new MethodResultInfo(to, checkContext);
943        }
944
945        @Override
946        public MethodCheck mostSpecificCheck(List<Type> actuals) {
947            return new MostSpecificCheck(actuals);
948        }
949
950        @Override
951        public String toString() {
952            return "MethodReferenceCheck";
953        }
954    }
955
956    /**
957     * Check context to be used during method applicability checks. A method check
958     * context might contain inference variables.
959     */
960    abstract class MethodCheckContext implements CheckContext {
961
962        boolean strict;
963        DeferredAttrContext deferredAttrContext;
964        Warner rsWarner;
965
966        public MethodCheckContext(boolean strict, DeferredAttrContext deferredAttrContext, Warner rsWarner) {
967           this.strict = strict;
968           this.deferredAttrContext = deferredAttrContext;
969           this.rsWarner = rsWarner;
970        }
971
972        public boolean compatible(Type found, Type req, Warner warn) {
973            InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
974            return strict ?
975                    types.isSubtypeUnchecked(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn) :
976                    types.isConvertible(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn);
977        }
978
979        public void report(DiagnosticPosition pos, JCDiagnostic details) {
980            throw inapplicableMethodException.setMessage(details);
981        }
982
983        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
984            return rsWarner;
985        }
986
987        public InferenceContext inferenceContext() {
988            return deferredAttrContext.inferenceContext;
989        }
990
991        public DeferredAttrContext deferredAttrContext() {
992            return deferredAttrContext;
993        }
994
995        @Override
996        public String toString() {
997            return "MethodCheckContext";
998        }
999    }
1000
1001    /**
1002     * ResultInfo class to be used during method applicability checks. Check
1003     * for deferred types goes through special path.
1004     */
1005    class MethodResultInfo extends ResultInfo {
1006
1007        public MethodResultInfo(Type pt, CheckContext checkContext) {
1008            attr.super(KindSelector.VAL, pt, checkContext);
1009        }
1010
1011        @Override
1012        protected Type check(DiagnosticPosition pos, Type found) {
1013            if (found.hasTag(DEFERRED)) {
1014                DeferredType dt = (DeferredType)found;
1015                return dt.check(this);
1016            } else {
1017                Type uResult = U(found);
1018                Type capturedType = pos == null || pos.getTree() == null ?
1019                        types.capture(uResult) :
1020                        checkContext.inferenceContext()
1021                            .cachedCapture(pos.getTree(), uResult, true);
1022                return super.check(pos, chk.checkNonVoid(pos, capturedType));
1023            }
1024        }
1025
1026        /**
1027         * javac has a long-standing 'simplification' (see 6391995):
1028         * given an actual argument type, the method check is performed
1029         * on its upper bound. This leads to inconsistencies when an
1030         * argument type is checked against itself. For example, given
1031         * a type-variable T, it is not true that {@code U(T) <: T},
1032         * so we need to guard against that.
1033         */
1034        private Type U(Type found) {
1035            return found == pt ?
1036                    found : types.cvarUpperBound(found);
1037        }
1038
1039        @Override
1040        protected MethodResultInfo dup(Type newPt) {
1041            return new MethodResultInfo(newPt, checkContext);
1042        }
1043
1044        @Override
1045        protected ResultInfo dup(CheckContext newContext) {
1046            return new MethodResultInfo(pt, newContext);
1047        }
1048
1049        @Override
1050        protected ResultInfo dup(Type newPt, CheckContext newContext) {
1051            return new MethodResultInfo(newPt, newContext);
1052        }
1053    }
1054
1055    /**
1056     * Most specific method applicability routine. Given a list of actual types A,
1057     * a list of formal types F1, and a list of formal types F2, the routine determines
1058     * as to whether the types in F1 can be considered more specific than those in F2 w.r.t.
1059     * argument types A.
1060     */
1061    class MostSpecificCheck implements MethodCheck {
1062
1063        List<Type> actuals;
1064
1065        MostSpecificCheck(List<Type> actuals) {
1066            this.actuals = actuals;
1067        }
1068
1069        @Override
1070        public void argumentsAcceptable(final Env<AttrContext> env,
1071                                    DeferredAttrContext deferredAttrContext,
1072                                    List<Type> formals1,
1073                                    List<Type> formals2,
1074                                    Warner warn) {
1075            formals2 = adjustArgs(formals2, deferredAttrContext.msym, formals1.length(), deferredAttrContext.phase.isVarargsRequired());
1076            while (formals2.nonEmpty()) {
1077                ResultInfo mresult = methodCheckResult(formals2.head, deferredAttrContext, warn, actuals.head);
1078                mresult.check(null, formals1.head);
1079                formals1 = formals1.tail;
1080                formals2 = formals2.tail;
1081                actuals = actuals.isEmpty() ? actuals : actuals.tail;
1082            }
1083        }
1084
1085       /**
1086        * Create a method check context to be used during the most specific applicability check
1087        */
1088        ResultInfo methodCheckResult(Type to, DeferredAttr.DeferredAttrContext deferredAttrContext,
1089               Warner rsWarner, Type actual) {
1090            return attr.new ResultInfo(KindSelector.VAL, to,
1091                   new MostSpecificCheckContext(deferredAttrContext, rsWarner, actual));
1092        }
1093
1094        /**
1095         * Subclass of method check context class that implements most specific
1096         * method conversion. If the actual type under analysis is a deferred type
1097         * a full blown structural analysis is carried out.
1098         */
1099        class MostSpecificCheckContext extends MethodCheckContext {
1100
1101            Type actual;
1102
1103            public MostSpecificCheckContext(DeferredAttrContext deferredAttrContext, Warner rsWarner, Type actual) {
1104                super(true, deferredAttrContext, rsWarner);
1105                this.actual = actual;
1106            }
1107
1108            public boolean compatible(Type found, Type req, Warner warn) {
1109                if (allowFunctionalInterfaceMostSpecific &&
1110                        unrelatedFunctionalInterfaces(found, req) &&
1111                        (actual != null && actual.getTag() == DEFERRED)) {
1112                    DeferredType dt = (DeferredType) actual;
1113                    JCTree speculativeTree = dt.speculativeTree(deferredAttrContext);
1114                    if (speculativeTree != deferredAttr.stuckTree) {
1115                        return functionalInterfaceMostSpecific(found, req, speculativeTree);
1116                    }
1117                }
1118                return compatibleBySubtyping(found, req);
1119            }
1120
1121            private boolean compatibleBySubtyping(Type found, Type req) {
1122                if (!strict && found.isPrimitive() != req.isPrimitive()) {
1123                    found = found.isPrimitive() ? types.boxedClass(found).type : types.unboxedType(found);
1124                }
1125                return types.isSubtypeNoCapture(found, deferredAttrContext.inferenceContext.asUndetVar(req));
1126            }
1127
1128            /** Whether {@code t} and {@code s} are unrelated functional interface types. */
1129            private boolean unrelatedFunctionalInterfaces(Type t, Type s) {
1130                return types.isFunctionalInterface(t.tsym) &&
1131                       types.isFunctionalInterface(s.tsym) &&
1132                       types.asSuper(t, s.tsym) == null &&
1133                       types.asSuper(s, t.tsym) == null;
1134            }
1135
1136            /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
1137            private boolean functionalInterfaceMostSpecific(Type t, Type s, JCTree tree) {
1138                Type tDesc = types.findDescriptorType(t);
1139                Type sDesc = types.findDescriptorType(s);
1140
1141                // compare type parameters -- can't use Types.hasSameBounds because bounds may have ivars
1142                final List<Type> tTypeParams = tDesc.getTypeArguments();
1143                final List<Type> sTypeParams = sDesc.getTypeArguments();
1144                List<Type> tIter = tTypeParams;
1145                List<Type> sIter = sTypeParams;
1146                while (tIter.nonEmpty() && sIter.nonEmpty()) {
1147                    Type tBound = tIter.head.getUpperBound();
1148                    Type sBound = types.subst(sIter.head.getUpperBound(), sTypeParams, tTypeParams);
1149                    if (tBound.containsAny(tTypeParams) && inferenceContext().free(sBound)) {
1150                        return false;
1151                    }
1152                    if (!types.isSameType(tBound, inferenceContext().asUndetVar(sBound))) {
1153                        return false;
1154                    }
1155                    tIter = tIter.tail;
1156                    sIter = sIter.tail;
1157                }
1158                if (!tIter.isEmpty() || !sIter.isEmpty()) {
1159                    return false;
1160                }
1161
1162                // compare parameters
1163                List<Type> tParams = tDesc.getParameterTypes();
1164                List<Type> sParams = sDesc.getParameterTypes();
1165                while (tParams.nonEmpty() && sParams.nonEmpty()) {
1166                    Type tParam = tParams.head;
1167                    Type sParam = types.subst(sParams.head, sTypeParams, tTypeParams);
1168                    if (tParam.containsAny(tTypeParams) && inferenceContext().free(sParam)) {
1169                        return false;
1170                    }
1171                    if (!types.isSameType(tParam, inferenceContext().asUndetVar(sParam))) {
1172                        return false;
1173                    }
1174                    tParams = tParams.tail;
1175                    sParams = sParams.tail;
1176                }
1177                if (!tParams.isEmpty() || !sParams.isEmpty()) {
1178                    return false;
1179                }
1180
1181                // compare returns
1182                Type tRet = tDesc.getReturnType();
1183                Type sRet = types.subst(sDesc.getReturnType(), sTypeParams, tTypeParams);
1184                if (tRet.containsAny(tTypeParams) && inferenceContext().free(sRet)) {
1185                    return false;
1186                }
1187                MostSpecificFunctionReturnChecker msc = new MostSpecificFunctionReturnChecker(tRet, sRet);
1188                msc.scan(tree);
1189                return msc.result;
1190            }
1191
1192            /**
1193             * Tests whether one functional interface type can be considered more specific
1194             * than another unrelated functional interface type for the scanned expression.
1195             */
1196            class MostSpecificFunctionReturnChecker extends DeferredAttr.PolyScanner {
1197
1198                final Type tRet;
1199                final Type sRet;
1200                boolean result;
1201
1202                /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
1203                MostSpecificFunctionReturnChecker(Type tRet, Type sRet) {
1204                    this.tRet = tRet;
1205                    this.sRet = sRet;
1206                    result = true;
1207                }
1208
1209                @Override
1210                void skip(JCTree tree) {
1211                    result &= false;
1212                }
1213
1214                @Override
1215                public void visitConditional(JCConditional tree) {
1216                    scan(asExpr(tree.truepart));
1217                    scan(asExpr(tree.falsepart));
1218                }
1219
1220                @Override
1221                public void visitReference(JCMemberReference tree) {
1222                    if (sRet.hasTag(VOID)) {
1223                        result &= true;
1224                    } else if (tRet.hasTag(VOID)) {
1225                        result &= false;
1226                    } else if (tRet.isPrimitive() != sRet.isPrimitive()) {
1227                        boolean retValIsPrimitive =
1228                                tree.refPolyKind == PolyKind.STANDALONE &&
1229                                tree.sym.type.getReturnType().isPrimitive();
1230                        result &= (retValIsPrimitive == tRet.isPrimitive()) &&
1231                                  (retValIsPrimitive != sRet.isPrimitive());
1232                    } else {
1233                        result &= compatibleBySubtyping(tRet, sRet);
1234                    }
1235                }
1236
1237                @Override
1238                public void visitParens(JCParens tree) {
1239                    scan(asExpr(tree.expr));
1240                }
1241
1242                @Override
1243                public void visitLambda(JCLambda tree) {
1244                    if (sRet.hasTag(VOID)) {
1245                        result &= true;
1246                    } else if (tRet.hasTag(VOID)) {
1247                        result &= false;
1248                    } else {
1249                        List<JCExpression> lambdaResults = lambdaResults(tree);
1250                        if (!lambdaResults.isEmpty() && unrelatedFunctionalInterfaces(tRet, sRet)) {
1251                            for (JCExpression expr : lambdaResults) {
1252                                result &= functionalInterfaceMostSpecific(tRet, sRet, expr);
1253                            }
1254                        } else if (!lambdaResults.isEmpty() && tRet.isPrimitive() != sRet.isPrimitive()) {
1255                            for (JCExpression expr : lambdaResults) {
1256                                boolean retValIsPrimitive = expr.isStandalone() && expr.type.isPrimitive();
1257                                result &= (retValIsPrimitive == tRet.isPrimitive()) &&
1258                                        (retValIsPrimitive != sRet.isPrimitive());
1259                            }
1260                        } else {
1261                            result &= compatibleBySubtyping(tRet, sRet);
1262                        }
1263                    }
1264                }
1265                //where
1266
1267                private List<JCExpression> lambdaResults(JCLambda lambda) {
1268                    if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) {
1269                        return List.of(asExpr((JCExpression) lambda.body));
1270                    } else {
1271                        final ListBuffer<JCExpression> buffer = new ListBuffer<>();
1272                        DeferredAttr.LambdaReturnScanner lambdaScanner =
1273                                new DeferredAttr.LambdaReturnScanner() {
1274                                    @Override
1275                                    public void visitReturn(JCReturn tree) {
1276                                        if (tree.expr != null) {
1277                                            buffer.append(asExpr(tree.expr));
1278                                        }
1279                                    }
1280                                };
1281                        lambdaScanner.scan(lambda.body);
1282                        return buffer.toList();
1283                    }
1284                }
1285
1286                private JCExpression asExpr(JCExpression expr) {
1287                    if (expr.type.hasTag(DEFERRED)) {
1288                        JCTree speculativeTree = ((DeferredType)expr.type).speculativeTree(deferredAttrContext);
1289                        if (speculativeTree != deferredAttr.stuckTree) {
1290                            expr = (JCExpression)speculativeTree;
1291                        }
1292                    }
1293                    return expr;
1294                }
1295            }
1296
1297        }
1298
1299        public MethodCheck mostSpecificCheck(List<Type> actuals) {
1300            Assert.error("Cannot get here!");
1301            return null;
1302        }
1303    }
1304
1305    public static class InapplicableMethodException extends RuntimeException {
1306        private static final long serialVersionUID = 0;
1307
1308        JCDiagnostic diagnostic;
1309        JCDiagnostic.Factory diags;
1310
1311        InapplicableMethodException(JCDiagnostic.Factory diags) {
1312            this.diagnostic = null;
1313            this.diags = diags;
1314        }
1315        InapplicableMethodException setMessage() {
1316            return setMessage((JCDiagnostic)null);
1317        }
1318        InapplicableMethodException setMessage(String key) {
1319            return setMessage(key != null ? diags.fragment(key) : null);
1320        }
1321        InapplicableMethodException setMessage(String key, Object... args) {
1322            return setMessage(key != null ? diags.fragment(key, args) : null);
1323        }
1324        InapplicableMethodException setMessage(JCDiagnostic diag) {
1325            this.diagnostic = diag;
1326            return this;
1327        }
1328
1329        public JCDiagnostic getDiagnostic() {
1330            return diagnostic;
1331        }
1332    }
1333    private final InapplicableMethodException inapplicableMethodException;
1334
1335/* ***************************************************************************
1336 *  Symbol lookup
1337 *  the following naming conventions for arguments are used
1338 *
1339 *       env      is the environment where the symbol was mentioned
1340 *       site     is the type of which the symbol is a member
1341 *       name     is the symbol's name
1342 *                if no arguments are given
1343 *       argtypes are the value arguments, if we search for a method
1344 *
1345 *  If no symbol was found, a ResolveError detailing the problem is returned.
1346 ****************************************************************************/
1347
1348    /** Find field. Synthetic fields are always skipped.
1349     *  @param env     The current environment.
1350     *  @param site    The original type from where the selection takes place.
1351     *  @param name    The name of the field.
1352     *  @param c       The class to search for the field. This is always
1353     *                 a superclass or implemented interface of site's class.
1354     */
1355    Symbol findField(Env<AttrContext> env,
1356                     Type site,
1357                     Name name,
1358                     TypeSymbol c) {
1359        while (c.type.hasTag(TYPEVAR))
1360            c = c.type.getUpperBound().tsym;
1361        Symbol bestSoFar = varNotFound;
1362        Symbol sym;
1363        for (Symbol s : c.members().getSymbolsByName(name)) {
1364            if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
1365                return isAccessible(env, site, s)
1366                    ? s : new AccessError(env, site, s);
1367            }
1368        }
1369        Type st = types.supertype(c.type);
1370        if (st != null && (st.hasTag(CLASS) || st.hasTag(TYPEVAR))) {
1371            sym = findField(env, site, name, st.tsym);
1372            bestSoFar = bestOf(bestSoFar, sym);
1373        }
1374        for (List<Type> l = types.interfaces(c.type);
1375             bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
1376             l = l.tail) {
1377            sym = findField(env, site, name, l.head.tsym);
1378            if (bestSoFar.exists() && sym.exists() &&
1379                sym.owner != bestSoFar.owner)
1380                bestSoFar = new AmbiguityError(bestSoFar, sym);
1381            else
1382                bestSoFar = bestOf(bestSoFar, sym);
1383        }
1384        return bestSoFar;
1385    }
1386
1387    /** Resolve a field identifier, throw a fatal error if not found.
1388     *  @param pos       The position to use for error reporting.
1389     *  @param env       The environment current at the method invocation.
1390     *  @param site      The type of the qualifying expression, in which
1391     *                   identifier is searched.
1392     *  @param name      The identifier's name.
1393     */
1394    public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env,
1395                                          Type site, Name name) {
1396        Symbol sym = findField(env, site, name, site.tsym);
1397        if (sym.kind == VAR) return (VarSymbol)sym;
1398        else throw new FatalError(
1399                 diags.fragment("fatal.err.cant.locate.field",
1400                                name));
1401    }
1402
1403    /** Find unqualified variable or field with given name.
1404     *  Synthetic fields always skipped.
1405     *  @param env     The current environment.
1406     *  @param name    The name of the variable or field.
1407     */
1408    Symbol findVar(Env<AttrContext> env, Name name) {
1409        Symbol bestSoFar = varNotFound;
1410        Env<AttrContext> env1 = env;
1411        boolean staticOnly = false;
1412        while (env1.outer != null) {
1413            Symbol sym = null;
1414            if (isStatic(env1)) staticOnly = true;
1415            for (Symbol s : env1.info.scope.getSymbolsByName(name)) {
1416                if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
1417                    sym = s;
1418                    break;
1419                }
1420            }
1421            if (sym == null) {
1422                sym = findField(env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
1423            }
1424            if (sym.exists()) {
1425                if (staticOnly &&
1426                    sym.kind == VAR &&
1427                    sym.owner.kind == TYP &&
1428                    (sym.flags() & STATIC) == 0)
1429                    return new StaticError(sym);
1430                else
1431                    return sym;
1432            } else {
1433                bestSoFar = bestOf(bestSoFar, sym);
1434            }
1435
1436            if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
1437            env1 = env1.outer;
1438        }
1439
1440        Symbol sym = findField(env, syms.predefClass.type, name, syms.predefClass);
1441        if (sym.exists())
1442            return sym;
1443        if (bestSoFar.exists())
1444            return bestSoFar;
1445
1446        Symbol origin = null;
1447        for (Scope sc : new Scope[] { env.toplevel.namedImportScope, env.toplevel.starImportScope }) {
1448            for (Symbol currentSymbol : sc.getSymbolsByName(name)) {
1449                if (currentSymbol.kind != VAR)
1450                    continue;
1451                // invariant: sym.kind == Symbol.Kind.VAR
1452                if (!bestSoFar.kind.isResolutionError() &&
1453                    currentSymbol.owner != bestSoFar.owner)
1454                    return new AmbiguityError(bestSoFar, currentSymbol);
1455                else if (!bestSoFar.kind.betterThan(VAR)) {
1456                    origin = sc.getOrigin(currentSymbol).owner;
1457                    bestSoFar = isAccessible(env, origin.type, currentSymbol)
1458                        ? currentSymbol : new AccessError(env, origin.type, currentSymbol);
1459                }
1460            }
1461            if (bestSoFar.exists()) break;
1462        }
1463        if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type)
1464            return bestSoFar.clone(origin);
1465        else
1466            return bestSoFar;
1467    }
1468
1469    Warner noteWarner = new Warner();
1470
1471    /** Select the best method for a call site among two choices.
1472     *  @param env              The current environment.
1473     *  @param site             The original type from where the
1474     *                          selection takes place.
1475     *  @param argtypes         The invocation's value arguments,
1476     *  @param typeargtypes     The invocation's type arguments,
1477     *  @param sym              Proposed new best match.
1478     *  @param bestSoFar        Previously found best match.
1479     *  @param allowBoxing Allow boxing conversions of arguments.
1480     *  @param useVarargs Box trailing arguments into an array for varargs.
1481     */
1482    @SuppressWarnings("fallthrough")
1483    Symbol selectBest(Env<AttrContext> env,
1484                      Type site,
1485                      List<Type> argtypes,
1486                      List<Type> typeargtypes,
1487                      Symbol sym,
1488                      Symbol bestSoFar,
1489                      boolean allowBoxing,
1490                      boolean useVarargs) {
1491        if (sym.kind == ERR ||
1492                !sym.isInheritedIn(site.tsym, types)) {
1493            return bestSoFar;
1494        } else if (useVarargs && (sym.flags() & VARARGS) == 0) {
1495            return bestSoFar.kind.isResolutionError() ?
1496                    new BadVarargsMethod((ResolveError)bestSoFar.baseSymbol()) :
1497                    bestSoFar;
1498        }
1499        Assert.check(!sym.kind.isResolutionError());
1500        try {
1501            types.noWarnings.clear();
1502            Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes,
1503                               allowBoxing, useVarargs, types.noWarnings);
1504            currentResolutionContext.addApplicableCandidate(sym, mt);
1505        } catch (InapplicableMethodException ex) {
1506            currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic());
1507            switch (bestSoFar.kind) {
1508                case ABSENT_MTH:
1509                    return new InapplicableSymbolError(currentResolutionContext);
1510                case WRONG_MTH:
1511                    bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
1512                default:
1513                    return bestSoFar;
1514            }
1515        }
1516        if (!isAccessible(env, site, sym)) {
1517            return (bestSoFar.kind == ABSENT_MTH)
1518                ? new AccessError(env, site, sym)
1519                : bestSoFar;
1520        }
1521        return (bestSoFar.kind.isResolutionError() && bestSoFar.kind != AMBIGUOUS)
1522            ? sym
1523            : mostSpecific(argtypes, sym, bestSoFar, env, site, useVarargs);
1524    }
1525
1526    /* Return the most specific of the two methods for a call,
1527     *  given that both are accessible and applicable.
1528     *  @param m1               A new candidate for most specific.
1529     *  @param m2               The previous most specific candidate.
1530     *  @param env              The current environment.
1531     *  @param site             The original type from where the selection
1532     *                          takes place.
1533     *  @param allowBoxing Allow boxing conversions of arguments.
1534     *  @param useVarargs Box trailing arguments into an array for varargs.
1535     */
1536    Symbol mostSpecific(List<Type> argtypes, Symbol m1,
1537                        Symbol m2,
1538                        Env<AttrContext> env,
1539                        final Type site,
1540                        boolean useVarargs) {
1541        switch (m2.kind) {
1542        case MTH:
1543            if (m1 == m2) return m1;
1544            boolean m1SignatureMoreSpecific =
1545                    signatureMoreSpecific(argtypes, env, site, m1, m2, useVarargs);
1546            boolean m2SignatureMoreSpecific =
1547                    signatureMoreSpecific(argtypes, env, site, m2, m1, useVarargs);
1548            if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) {
1549                Type mt1 = types.memberType(site, m1);
1550                Type mt2 = types.memberType(site, m2);
1551                if (!types.overrideEquivalent(mt1, mt2))
1552                    return ambiguityError(m1, m2);
1553
1554                // same signature; select (a) the non-bridge method, or
1555                // (b) the one that overrides the other, or (c) the concrete
1556                // one, or (d) merge both abstract signatures
1557                if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE))
1558                    return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
1559
1560                // if one overrides or hides the other, use it
1561                TypeSymbol m1Owner = (TypeSymbol)m1.owner;
1562                TypeSymbol m2Owner = (TypeSymbol)m2.owner;
1563                if (types.asSuper(m1Owner.type, m2Owner) != null &&
1564                    ((m1.owner.flags_field & INTERFACE) == 0 ||
1565                     (m2.owner.flags_field & INTERFACE) != 0) &&
1566                    m1.overrides(m2, m1Owner, types, false))
1567                    return m1;
1568                if (types.asSuper(m2Owner.type, m1Owner) != null &&
1569                    ((m2.owner.flags_field & INTERFACE) == 0 ||
1570                     (m1.owner.flags_field & INTERFACE) != 0) &&
1571                    m2.overrides(m1, m2Owner, types, false))
1572                    return m2;
1573                boolean m1Abstract = (m1.flags() & ABSTRACT) != 0;
1574                boolean m2Abstract = (m2.flags() & ABSTRACT) != 0;
1575                if (m1Abstract && !m2Abstract) return m2;
1576                if (m2Abstract && !m1Abstract) return m1;
1577                // both abstract or both concrete
1578                return ambiguityError(m1, m2);
1579            }
1580            if (m1SignatureMoreSpecific) return m1;
1581            if (m2SignatureMoreSpecific) return m2;
1582            return ambiguityError(m1, m2);
1583        case AMBIGUOUS:
1584            //compare m1 to ambiguous methods in m2
1585            AmbiguityError e = (AmbiguityError)m2.baseSymbol();
1586            boolean m1MoreSpecificThanAnyAmbiguous = true;
1587            boolean allAmbiguousMoreSpecificThanM1 = true;
1588            for (Symbol s : e.ambiguousSyms) {
1589                Symbol moreSpecific = mostSpecific(argtypes, m1, s, env, site, useVarargs);
1590                m1MoreSpecificThanAnyAmbiguous &= moreSpecific == m1;
1591                allAmbiguousMoreSpecificThanM1 &= moreSpecific == s;
1592            }
1593            if (m1MoreSpecificThanAnyAmbiguous)
1594                return m1;
1595            //if m1 is more specific than some ambiguous methods, but other ambiguous methods are
1596            //more specific than m1, add it as a new ambiguous method:
1597            if (!allAmbiguousMoreSpecificThanM1)
1598                e.addAmbiguousSymbol(m1);
1599            return e;
1600        default:
1601            throw new AssertionError();
1602        }
1603    }
1604    //where
1605    private boolean signatureMoreSpecific(List<Type> actuals, Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean useVarargs) {
1606        noteWarner.clear();
1607        int maxLength = Math.max(
1608                            Math.max(m1.type.getParameterTypes().length(), actuals.length()),
1609                            m2.type.getParameterTypes().length());
1610        MethodResolutionContext prevResolutionContext = currentResolutionContext;
1611        try {
1612            currentResolutionContext = new MethodResolutionContext();
1613            currentResolutionContext.step = prevResolutionContext.step;
1614            currentResolutionContext.methodCheck =
1615                    prevResolutionContext.methodCheck.mostSpecificCheck(actuals);
1616            Type mst = instantiate(env, site, m2, null,
1617                    adjustArgs(types.cvarLowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null,
1618                    false, useVarargs, noteWarner);
1619            return mst != null &&
1620                    !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
1621        } finally {
1622            currentResolutionContext = prevResolutionContext;
1623        }
1624    }
1625
1626    List<Type> adjustArgs(List<Type> args, Symbol msym, int length, boolean allowVarargs) {
1627        if ((msym.flags() & VARARGS) != 0 && allowVarargs) {
1628            Type varargsElem = types.elemtype(args.last());
1629            if (varargsElem == null) {
1630                Assert.error("Bad varargs = " + args.last() + " " + msym);
1631            }
1632            List<Type> newArgs = args.reverse().tail.prepend(varargsElem).reverse();
1633            while (newArgs.length() < length) {
1634                newArgs = newArgs.append(newArgs.last());
1635            }
1636            return newArgs;
1637        } else {
1638            return args;
1639        }
1640    }
1641    //where
1642    Type mostSpecificReturnType(Type mt1, Type mt2) {
1643        Type rt1 = mt1.getReturnType();
1644        Type rt2 = mt2.getReturnType();
1645
1646        if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL)) {
1647            //if both are generic methods, adjust return type ahead of subtyping check
1648            rt1 = types.subst(rt1, mt1.getTypeArguments(), mt2.getTypeArguments());
1649        }
1650        //first use subtyping, then return type substitutability
1651        if (types.isSubtype(rt1, rt2)) {
1652            return mt1;
1653        } else if (types.isSubtype(rt2, rt1)) {
1654            return mt2;
1655        } else if (types.returnTypeSubstitutable(mt1, mt2)) {
1656            return mt1;
1657        } else if (types.returnTypeSubstitutable(mt2, mt1)) {
1658            return mt2;
1659        } else {
1660            return null;
1661        }
1662    }
1663    //where
1664    Symbol ambiguityError(Symbol m1, Symbol m2) {
1665        if (((m1.flags() | m2.flags()) & CLASH) != 0) {
1666            return (m1.flags() & CLASH) == 0 ? m1 : m2;
1667        } else {
1668            return new AmbiguityError(m1, m2);
1669        }
1670    }
1671
1672    Symbol findMethodInScope(Env<AttrContext> env,
1673            Type site,
1674            Name name,
1675            List<Type> argtypes,
1676            List<Type> typeargtypes,
1677            Scope sc,
1678            Symbol bestSoFar,
1679            boolean allowBoxing,
1680            boolean useVarargs,
1681            boolean abstractok) {
1682        for (Symbol s : sc.getSymbolsByName(name, new LookupFilter(abstractok))) {
1683            bestSoFar = selectBest(env, site, argtypes, typeargtypes, s,
1684                    bestSoFar, allowBoxing, useVarargs);
1685        }
1686        return bestSoFar;
1687    }
1688    //where
1689        class LookupFilter implements Filter<Symbol> {
1690
1691            boolean abstractOk;
1692
1693            LookupFilter(boolean abstractOk) {
1694                this.abstractOk = abstractOk;
1695            }
1696
1697            public boolean accepts(Symbol s) {
1698                long flags = s.flags();
1699                return s.kind == MTH &&
1700                        (flags & SYNTHETIC) == 0 &&
1701                        (abstractOk ||
1702                        (flags & DEFAULT) != 0 ||
1703                        (flags & ABSTRACT) == 0);
1704            }
1705        }
1706
1707    /** Find best qualified method matching given name, type and value
1708     *  arguments.
1709     *  @param env       The current environment.
1710     *  @param site      The original type from where the selection
1711     *                   takes place.
1712     *  @param name      The method's name.
1713     *  @param argtypes  The method's value arguments.
1714     *  @param typeargtypes The method's type arguments
1715     *  @param allowBoxing Allow boxing conversions of arguments.
1716     *  @param useVarargs Box trailing arguments into an array for varargs.
1717     */
1718    Symbol findMethod(Env<AttrContext> env,
1719                      Type site,
1720                      Name name,
1721                      List<Type> argtypes,
1722                      List<Type> typeargtypes,
1723                      boolean allowBoxing,
1724                      boolean useVarargs) {
1725        Symbol bestSoFar = methodNotFound;
1726        bestSoFar = findMethod(env,
1727                          site,
1728                          name,
1729                          argtypes,
1730                          typeargtypes,
1731                          site.tsym.type,
1732                          bestSoFar,
1733                          allowBoxing,
1734                          useVarargs);
1735        return bestSoFar;
1736    }
1737    // where
1738    private Symbol findMethod(Env<AttrContext> env,
1739                              Type site,
1740                              Name name,
1741                              List<Type> argtypes,
1742                              List<Type> typeargtypes,
1743                              Type intype,
1744                              Symbol bestSoFar,
1745                              boolean allowBoxing,
1746                              boolean useVarargs) {
1747        @SuppressWarnings({"unchecked","rawtypes"})
1748        List<Type>[] itypes = (List<Type>[])new List[] { List.<Type>nil(), List.<Type>nil() };
1749
1750        InterfaceLookupPhase iphase = InterfaceLookupPhase.ABSTRACT_OK;
1751        for (TypeSymbol s : superclasses(intype)) {
1752            bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1753                    s.members(), bestSoFar, allowBoxing, useVarargs, true);
1754            if (name == names.init) return bestSoFar;
1755            iphase = (iphase == null) ? null : iphase.update(s, this);
1756            if (iphase != null) {
1757                for (Type itype : types.interfaces(s.type)) {
1758                    itypes[iphase.ordinal()] = types.union(types.closure(itype), itypes[iphase.ordinal()]);
1759                }
1760            }
1761        }
1762
1763        Symbol concrete = bestSoFar.kind.isValid() &&
1764                (bestSoFar.flags() & ABSTRACT) == 0 ?
1765                bestSoFar : methodNotFound;
1766
1767        for (InterfaceLookupPhase iphase2 : InterfaceLookupPhase.values()) {
1768            //keep searching for abstract methods
1769            for (Type itype : itypes[iphase2.ordinal()]) {
1770                if (!itype.isInterface()) continue; //skip j.l.Object (included by Types.closure())
1771                if (iphase2 == InterfaceLookupPhase.DEFAULT_OK &&
1772                        (itype.tsym.flags() & DEFAULT) == 0) continue;
1773                bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1774                        itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, true);
1775                if (concrete != bestSoFar &&
1776                    concrete.kind.isValid() &&
1777                    bestSoFar.kind.isValid() &&
1778                        types.isSubSignature(concrete.type, bestSoFar.type)) {
1779                    //this is an hack - as javac does not do full membership checks
1780                    //most specific ends up comparing abstract methods that might have
1781                    //been implemented by some concrete method in a subclass and,
1782                    //because of raw override, it is possible for an abstract method
1783                    //to be more specific than the concrete method - so we need
1784                    //to explicitly call that out (see CR 6178365)
1785                    bestSoFar = concrete;
1786                }
1787            }
1788        }
1789        return bestSoFar;
1790    }
1791
1792    enum InterfaceLookupPhase {
1793        ABSTRACT_OK() {
1794            @Override
1795            InterfaceLookupPhase update(Symbol s, Resolve rs) {
1796                //We should not look for abstract methods if receiver is a concrete class
1797                //(as concrete classes are expected to implement all abstracts coming
1798                //from superinterfaces)
1799                if ((s.flags() & (ABSTRACT | INTERFACE | ENUM)) != 0) {
1800                    return this;
1801                } else {
1802                    return DEFAULT_OK;
1803                }
1804            }
1805        },
1806        DEFAULT_OK() {
1807            @Override
1808            InterfaceLookupPhase update(Symbol s, Resolve rs) {
1809                return this;
1810            }
1811        };
1812
1813        abstract InterfaceLookupPhase update(Symbol s, Resolve rs);
1814    }
1815
1816    /**
1817     * Return an Iterable object to scan the superclasses of a given type.
1818     * It's crucial that the scan is done lazily, as we don't want to accidentally
1819     * access more supertypes than strictly needed (as this could trigger completion
1820     * errors if some of the not-needed supertypes are missing/ill-formed).
1821     */
1822    Iterable<TypeSymbol> superclasses(final Type intype) {
1823        return new Iterable<TypeSymbol>() {
1824            public Iterator<TypeSymbol> iterator() {
1825                return new Iterator<TypeSymbol>() {
1826
1827                    List<TypeSymbol> seen = List.nil();
1828                    TypeSymbol currentSym = symbolFor(intype);
1829                    TypeSymbol prevSym = null;
1830
1831                    public boolean hasNext() {
1832                        if (currentSym == syms.noSymbol) {
1833                            currentSym = symbolFor(types.supertype(prevSym.type));
1834                        }
1835                        return currentSym != null;
1836                    }
1837
1838                    public TypeSymbol next() {
1839                        prevSym = currentSym;
1840                        currentSym = syms.noSymbol;
1841                        Assert.check(prevSym != null || prevSym != syms.noSymbol);
1842                        return prevSym;
1843                    }
1844
1845                    public void remove() {
1846                        throw new UnsupportedOperationException();
1847                    }
1848
1849                    TypeSymbol symbolFor(Type t) {
1850                        if (!t.hasTag(CLASS) &&
1851                                !t.hasTag(TYPEVAR)) {
1852                            return null;
1853                        }
1854                        t = types.skipTypeVars(t, false);
1855                        if (seen.contains(t.tsym)) {
1856                            //degenerate case in which we have a circular
1857                            //class hierarchy - because of ill-formed classfiles
1858                            return null;
1859                        }
1860                        seen = seen.prepend(t.tsym);
1861                        return t.tsym;
1862                    }
1863                };
1864            }
1865        };
1866    }
1867
1868    /** Find unqualified method matching given name, type and value arguments.
1869     *  @param env       The current environment.
1870     *  @param name      The method's name.
1871     *  @param argtypes  The method's value arguments.
1872     *  @param typeargtypes  The method's type arguments.
1873     *  @param allowBoxing Allow boxing conversions of arguments.
1874     *  @param useVarargs Box trailing arguments into an array for varargs.
1875     */
1876    Symbol findFun(Env<AttrContext> env, Name name,
1877                   List<Type> argtypes, List<Type> typeargtypes,
1878                   boolean allowBoxing, boolean useVarargs) {
1879        Symbol bestSoFar = methodNotFound;
1880        Env<AttrContext> env1 = env;
1881        boolean staticOnly = false;
1882        while (env1.outer != null) {
1883            if (isStatic(env1)) staticOnly = true;
1884            Assert.check(env1.info.preferredTreeForDiagnostics == null);
1885            env1.info.preferredTreeForDiagnostics = env.tree;
1886            try {
1887                Symbol sym = findMethod(
1888                    env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
1889                    allowBoxing, useVarargs);
1890                if (sym.exists()) {
1891                    if (staticOnly &&
1892                        sym.kind == MTH &&
1893                        sym.owner.kind == TYP &&
1894                        (sym.flags() & STATIC) == 0) return new StaticError(sym);
1895                    else return sym;
1896                } else {
1897                    bestSoFar = bestOf(bestSoFar, sym);
1898                }
1899            } finally {
1900                env1.info.preferredTreeForDiagnostics = null;
1901            }
1902            if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
1903            env1 = env1.outer;
1904        }
1905
1906        Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
1907                                typeargtypes, allowBoxing, useVarargs);
1908        if (sym.exists())
1909            return sym;
1910
1911        for (Symbol currentSym : env.toplevel.namedImportScope.getSymbolsByName(name)) {
1912            Symbol origin = env.toplevel.namedImportScope.getOrigin(currentSym).owner;
1913            if (currentSym.kind == MTH) {
1914                if (currentSym.owner.type != origin.type)
1915                    currentSym = currentSym.clone(origin);
1916                if (!isAccessible(env, origin.type, currentSym))
1917                    currentSym = new AccessError(env, origin.type, currentSym);
1918                bestSoFar = selectBest(env, origin.type,
1919                                       argtypes, typeargtypes,
1920                                       currentSym, bestSoFar,
1921                                       allowBoxing, useVarargs);
1922            }
1923        }
1924        if (bestSoFar.exists())
1925            return bestSoFar;
1926
1927        for (Symbol currentSym : env.toplevel.starImportScope.getSymbolsByName(name)) {
1928            Symbol origin = env.toplevel.starImportScope.getOrigin(currentSym).owner;
1929            if (currentSym.kind == MTH) {
1930                if (currentSym.owner.type != origin.type)
1931                    currentSym = currentSym.clone(origin);
1932                if (!isAccessible(env, origin.type, currentSym))
1933                    currentSym = new AccessError(env, origin.type, currentSym);
1934                bestSoFar = selectBest(env, origin.type,
1935                                       argtypes, typeargtypes,
1936                                       currentSym, bestSoFar,
1937                                       allowBoxing, useVarargs);
1938            }
1939        }
1940        return bestSoFar;
1941    }
1942
1943    /** Load toplevel or member class with given fully qualified name and
1944     *  verify that it is accessible.
1945     *  @param env       The current environment.
1946     *  @param name      The fully qualified name of the class to be loaded.
1947     */
1948    Symbol loadClass(Env<AttrContext> env, Name name) {
1949        try {
1950            ClassSymbol c = finder.loadClass(name);
1951            return isAccessible(env, c) ? c : new AccessError(c);
1952        } catch (ClassFinder.BadClassFile err) {
1953            throw err;
1954        } catch (CompletionFailure ex) {
1955            return typeNotFound;
1956        }
1957    }
1958
1959
1960    /**
1961     * Find a type declared in a scope (not inherited).  Return null
1962     * if none is found.
1963     *  @param env       The current environment.
1964     *  @param site      The original type from where the selection takes
1965     *                   place.
1966     *  @param name      The type's name.
1967     *  @param c         The class to search for the member type. This is
1968     *                   always a superclass or implemented interface of
1969     *                   site's class.
1970     */
1971    Symbol findImmediateMemberType(Env<AttrContext> env,
1972                                   Type site,
1973                                   Name name,
1974                                   TypeSymbol c) {
1975        for (Symbol sym : c.members().getSymbolsByName(name)) {
1976            if (sym.kind == TYP) {
1977                return isAccessible(env, site, sym)
1978                    ? sym
1979                    : new AccessError(env, site, sym);
1980            }
1981        }
1982        return typeNotFound;
1983    }
1984
1985    /** Find a member type inherited from a superclass or interface.
1986     *  @param env       The current environment.
1987     *  @param site      The original type from where the selection takes
1988     *                   place.
1989     *  @param name      The type's name.
1990     *  @param c         The class to search for the member type. This is
1991     *                   always a superclass or implemented interface of
1992     *                   site's class.
1993     */
1994    Symbol findInheritedMemberType(Env<AttrContext> env,
1995                                   Type site,
1996                                   Name name,
1997                                   TypeSymbol c) {
1998        Symbol bestSoFar = typeNotFound;
1999        Symbol sym;
2000        Type st = types.supertype(c.type);
2001        if (st != null && st.hasTag(CLASS)) {
2002            sym = findMemberType(env, site, name, st.tsym);
2003            bestSoFar = bestOf(bestSoFar, sym);
2004        }
2005        for (List<Type> l = types.interfaces(c.type);
2006             bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
2007             l = l.tail) {
2008            sym = findMemberType(env, site, name, l.head.tsym);
2009            if (!bestSoFar.kind.isResolutionError() &&
2010                !sym.kind.isResolutionError() &&
2011                sym.owner != bestSoFar.owner)
2012                bestSoFar = new AmbiguityError(bestSoFar, sym);
2013            else
2014                bestSoFar = bestOf(bestSoFar, sym);
2015        }
2016        return bestSoFar;
2017    }
2018
2019    /** Find qualified member type.
2020     *  @param env       The current environment.
2021     *  @param site      The original type from where the selection takes
2022     *                   place.
2023     *  @param name      The type's name.
2024     *  @param c         The class to search for the member type. This is
2025     *                   always a superclass or implemented interface of
2026     *                   site's class.
2027     */
2028    Symbol findMemberType(Env<AttrContext> env,
2029                          Type site,
2030                          Name name,
2031                          TypeSymbol c) {
2032        Symbol sym = findImmediateMemberType(env, site, name, c);
2033
2034        if (sym != typeNotFound)
2035            return sym;
2036
2037        return findInheritedMemberType(env, site, name, c);
2038
2039    }
2040
2041    /** Find a global type in given scope and load corresponding class.
2042     *  @param env       The current environment.
2043     *  @param scope     The scope in which to look for the type.
2044     *  @param name      The type's name.
2045     */
2046    Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {
2047        Symbol bestSoFar = typeNotFound;
2048        for (Symbol s : scope.getSymbolsByName(name)) {
2049            Symbol sym = loadClass(env, s.flatName());
2050            if (bestSoFar.kind == TYP && sym.kind == TYP &&
2051                bestSoFar != sym)
2052                return new AmbiguityError(bestSoFar, sym);
2053            else
2054                bestSoFar = bestOf(bestSoFar, sym);
2055        }
2056        return bestSoFar;
2057    }
2058
2059    Symbol findTypeVar(Env<AttrContext> env, Name name, boolean staticOnly) {
2060        for (Symbol sym : env.info.scope.getSymbolsByName(name)) {
2061            if (sym.kind == TYP) {
2062                if (staticOnly &&
2063                    sym.type.hasTag(TYPEVAR) &&
2064                    sym.owner.kind == TYP)
2065                    return new StaticError(sym);
2066                return sym;
2067            }
2068        }
2069        return typeNotFound;
2070    }
2071
2072    /** Find an unqualified type symbol.
2073     *  @param env       The current environment.
2074     *  @param name      The type's name.
2075     */
2076    Symbol findType(Env<AttrContext> env, Name name) {
2077        if (name == names.empty)
2078            return typeNotFound; // do not allow inadvertent "lookup" of anonymous types
2079        Symbol bestSoFar = typeNotFound;
2080        Symbol sym;
2081        boolean staticOnly = false;
2082        for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {
2083            if (isStatic(env1)) staticOnly = true;
2084            // First, look for a type variable and the first member type
2085            final Symbol tyvar = findTypeVar(env1, name, staticOnly);
2086            sym = findImmediateMemberType(env1, env1.enclClass.sym.type,
2087                                          name, env1.enclClass.sym);
2088
2089            // Return the type variable if we have it, and have no
2090            // immediate member, OR the type variable is for a method.
2091            if (tyvar != typeNotFound) {
2092                if (env.baseClause || sym == typeNotFound ||
2093                    (tyvar.kind == TYP && tyvar.exists() &&
2094                     tyvar.owner.kind == MTH)) {
2095                    return tyvar;
2096                }
2097            }
2098
2099            // If the environment is a class def, finish up,
2100            // otherwise, do the entire findMemberType
2101            if (sym == typeNotFound)
2102                sym = findInheritedMemberType(env1, env1.enclClass.sym.type,
2103                                              name, env1.enclClass.sym);
2104
2105            if (staticOnly && sym.kind == TYP &&
2106                sym.type.hasTag(CLASS) &&
2107                sym.type.getEnclosingType().hasTag(CLASS) &&
2108                env1.enclClass.sym.type.isParameterized() &&
2109                sym.type.getEnclosingType().isParameterized())
2110                return new StaticError(sym);
2111            else if (sym.exists()) return sym;
2112            else bestSoFar = bestOf(bestSoFar, sym);
2113
2114            JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass;
2115            if ((encl.sym.flags() & STATIC) != 0)
2116                staticOnly = true;
2117        }
2118
2119        if (!env.tree.hasTag(IMPORT)) {
2120            sym = findGlobalType(env, env.toplevel.namedImportScope, name);
2121            if (sym.exists()) return sym;
2122            else bestSoFar = bestOf(bestSoFar, sym);
2123
2124            sym = findGlobalType(env, env.toplevel.packge.members(), name);
2125            if (sym.exists()) return sym;
2126            else bestSoFar = bestOf(bestSoFar, sym);
2127
2128            sym = findGlobalType(env, env.toplevel.starImportScope, name);
2129            if (sym.exists()) return sym;
2130            else bestSoFar = bestOf(bestSoFar, sym);
2131        }
2132
2133        return bestSoFar;
2134    }
2135
2136    /** Find an unqualified identifier which matches a specified kind set.
2137     *  @param env       The current environment.
2138     *  @param name      The identifier's name.
2139     *  @param kind      Indicates the possible symbol kinds
2140     *                   (a subset of VAL, TYP, PCK).
2141     */
2142    Symbol findIdent(Env<AttrContext> env, Name name, KindSelector kind) {
2143        Symbol bestSoFar = typeNotFound;
2144        Symbol sym;
2145
2146        if (kind.contains(KindSelector.VAL)) {
2147            sym = findVar(env, name);
2148            if (sym.exists()) return sym;
2149            else bestSoFar = bestOf(bestSoFar, sym);
2150        }
2151
2152        if (kind.contains(KindSelector.TYP)) {
2153            sym = findType(env, name);
2154
2155            if (sym.exists()) return sym;
2156            else bestSoFar = bestOf(bestSoFar, sym);
2157        }
2158
2159        if (kind.contains(KindSelector.PCK))
2160            return syms.enterPackage(name);
2161        else return bestSoFar;
2162    }
2163
2164    /** Find an identifier in a package which matches a specified kind set.
2165     *  @param env       The current environment.
2166     *  @param name      The identifier's name.
2167     *  @param kind      Indicates the possible symbol kinds
2168     *                   (a nonempty subset of TYP, PCK).
2169     */
2170    Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck,
2171                              Name name, KindSelector kind) {
2172        Name fullname = TypeSymbol.formFullName(name, pck);
2173        Symbol bestSoFar = typeNotFound;
2174        PackageSymbol pack = null;
2175        if (kind.contains(KindSelector.PCK)) {
2176            pack = syms.enterPackage(fullname);
2177            if (pack.exists()) return pack;
2178        }
2179        if (kind.contains(KindSelector.TYP)) {
2180            Symbol sym = loadClass(env, fullname);
2181            if (sym.exists()) {
2182                // don't allow programs to use flatnames
2183                if (name == sym.name) return sym;
2184            }
2185            else bestSoFar = bestOf(bestSoFar, sym);
2186        }
2187        return (pack != null) ? pack : bestSoFar;
2188    }
2189
2190    /** Find an identifier among the members of a given type `site'.
2191     *  @param env       The current environment.
2192     *  @param site      The type containing the symbol to be found.
2193     *  @param name      The identifier's name.
2194     *  @param kind      Indicates the possible symbol kinds
2195     *                   (a subset of VAL, TYP).
2196     */
2197    Symbol findIdentInType(Env<AttrContext> env, Type site,
2198                           Name name, KindSelector kind) {
2199        Symbol bestSoFar = typeNotFound;
2200        Symbol sym;
2201        if (kind.contains(KindSelector.VAL)) {
2202            sym = findField(env, site, name, site.tsym);
2203            if (sym.exists()) return sym;
2204            else bestSoFar = bestOf(bestSoFar, sym);
2205        }
2206
2207        if (kind.contains(KindSelector.TYP)) {
2208            sym = findMemberType(env, site, name, site.tsym);
2209            if (sym.exists()) return sym;
2210            else bestSoFar = bestOf(bestSoFar, sym);
2211        }
2212        return bestSoFar;
2213    }
2214
2215/* ***************************************************************************
2216 *  Access checking
2217 *  The following methods convert ResolveErrors to ErrorSymbols, issuing
2218 *  an error message in the process
2219 ****************************************************************************/
2220
2221    /** If `sym' is a bad symbol: report error and return errSymbol
2222     *  else pass through unchanged,
2223     *  additional arguments duplicate what has been used in trying to find the
2224     *  symbol {@literal (--> flyweight pattern)}. This improves performance since we
2225     *  expect misses to happen frequently.
2226     *
2227     *  @param sym       The symbol that was found, or a ResolveError.
2228     *  @param pos       The position to use for error reporting.
2229     *  @param location  The symbol the served as a context for this lookup
2230     *  @param site      The original type from where the selection took place.
2231     *  @param name      The symbol's name.
2232     *  @param qualified Did we get here through a qualified expression resolution?
2233     *  @param argtypes  The invocation's value arguments,
2234     *                   if we looked for a method.
2235     *  @param typeargtypes  The invocation's type arguments,
2236     *                   if we looked for a method.
2237     *  @param logResolveHelper helper class used to log resolve errors
2238     */
2239    Symbol accessInternal(Symbol sym,
2240                  DiagnosticPosition pos,
2241                  Symbol location,
2242                  Type site,
2243                  Name name,
2244                  boolean qualified,
2245                  List<Type> argtypes,
2246                  List<Type> typeargtypes,
2247                  LogResolveHelper logResolveHelper) {
2248        if (sym.kind.isResolutionError()) {
2249            ResolveError errSym = (ResolveError)sym.baseSymbol();
2250            sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol);
2251            argtypes = logResolveHelper.getArgumentTypes(errSym, sym, name, argtypes);
2252            if (logResolveHelper.resolveDiagnosticNeeded(site, argtypes, typeargtypes)) {
2253                logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes);
2254            }
2255        }
2256        return sym;
2257    }
2258
2259    /**
2260     * Variant of the generalized access routine, to be used for generating method
2261     * resolution diagnostics
2262     */
2263    Symbol accessMethod(Symbol sym,
2264                  DiagnosticPosition pos,
2265                  Symbol location,
2266                  Type site,
2267                  Name name,
2268                  boolean qualified,
2269                  List<Type> argtypes,
2270                  List<Type> typeargtypes) {
2271        return accessInternal(sym, pos, location, site, name, qualified, argtypes, typeargtypes, methodLogResolveHelper);
2272    }
2273
2274    /** Same as original accessMethod(), but without location.
2275     */
2276    Symbol accessMethod(Symbol sym,
2277                  DiagnosticPosition pos,
2278                  Type site,
2279                  Name name,
2280                  boolean qualified,
2281                  List<Type> argtypes,
2282                  List<Type> typeargtypes) {
2283        return accessMethod(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes);
2284    }
2285
2286    /**
2287     * Variant of the generalized access routine, to be used for generating variable,
2288     * type resolution diagnostics
2289     */
2290    Symbol accessBase(Symbol sym,
2291                  DiagnosticPosition pos,
2292                  Symbol location,
2293                  Type site,
2294                  Name name,
2295                  boolean qualified) {
2296        return accessInternal(sym, pos, location, site, name, qualified, List.<Type>nil(), null, basicLogResolveHelper);
2297    }
2298
2299    /** Same as original accessBase(), but without location.
2300     */
2301    Symbol accessBase(Symbol sym,
2302                  DiagnosticPosition pos,
2303                  Type site,
2304                  Name name,
2305                  boolean qualified) {
2306        return accessBase(sym, pos, site.tsym, site, name, qualified);
2307    }
2308
2309    interface LogResolveHelper {
2310        boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes);
2311        List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes);
2312    }
2313
2314    LogResolveHelper basicLogResolveHelper = new LogResolveHelper() {
2315        public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2316            return !site.isErroneous();
2317        }
2318        public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2319            return argtypes;
2320        }
2321    };
2322
2323    LogResolveHelper methodLogResolveHelper = new LogResolveHelper() {
2324        public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2325            return !site.isErroneous() &&
2326                        !Type.isErroneous(argtypes) &&
2327                        (typeargtypes == null || !Type.isErroneous(typeargtypes));
2328        }
2329        public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2330            return argtypes.map(new ResolveDeferredRecoveryMap(AttrMode.SPECULATIVE, accessedSym, currentResolutionContext.step));
2331        }
2332    };
2333
2334    class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap {
2335
2336        public ResolveDeferredRecoveryMap(AttrMode mode, Symbol msym, MethodResolutionPhase step) {
2337            deferredAttr.super(mode, msym, step);
2338        }
2339
2340        @Override
2341        protected Type typeOf(DeferredType dt) {
2342            Type res = super.typeOf(dt);
2343            if (!res.isErroneous()) {
2344                switch (TreeInfo.skipParens(dt.tree).getTag()) {
2345                    case LAMBDA:
2346                    case REFERENCE:
2347                        return dt;
2348                    case CONDEXPR:
2349                        return res == Type.recoveryType ?
2350                                dt : res;
2351                }
2352            }
2353            return res;
2354        }
2355    }
2356
2357    /** Check that sym is not an abstract method.
2358     */
2359    void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
2360        if ((sym.flags() & ABSTRACT) != 0 && (sym.flags() & DEFAULT) == 0)
2361            log.error(pos, "abstract.cant.be.accessed.directly",
2362                      kindName(sym), sym, sym.location());
2363    }
2364
2365/* ***************************************************************************
2366 *  Name resolution
2367 *  Naming conventions are as for symbol lookup
2368 *  Unlike the find... methods these methods will report access errors
2369 ****************************************************************************/
2370
2371    /** Resolve an unqualified (non-method) identifier.
2372     *  @param pos       The position to use for error reporting.
2373     *  @param env       The environment current at the identifier use.
2374     *  @param name      The identifier's name.
2375     *  @param kind      The set of admissible symbol kinds for the identifier.
2376     */
2377    Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,
2378                        Name name, KindSelector kind) {
2379        return accessBase(
2380            findIdent(env, name, kind),
2381            pos, env.enclClass.sym.type, name, false);
2382    }
2383
2384    /** Resolve an unqualified method identifier.
2385     *  @param pos       The position to use for error reporting.
2386     *  @param env       The environment current at the method invocation.
2387     *  @param name      The identifier's name.
2388     *  @param argtypes  The types of the invocation's value arguments.
2389     *  @param typeargtypes  The types of the invocation's type arguments.
2390     */
2391    Symbol resolveMethod(DiagnosticPosition pos,
2392                         Env<AttrContext> env,
2393                         Name name,
2394                         List<Type> argtypes,
2395                         List<Type> typeargtypes) {
2396        return lookupMethod(env, pos, env.enclClass.sym, resolveMethodCheck,
2397                new BasicLookupHelper(name, env.enclClass.sym.type, argtypes, typeargtypes) {
2398                    @Override
2399                    Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2400                        return findFun(env, name, argtypes, typeargtypes,
2401                                phase.isBoxingRequired(),
2402                                phase.isVarargsRequired());
2403                    }});
2404    }
2405
2406    /** Resolve a qualified method identifier
2407     *  @param pos       The position to use for error reporting.
2408     *  @param env       The environment current at the method invocation.
2409     *  @param site      The type of the qualifying expression, in which
2410     *                   identifier is searched.
2411     *  @param name      The identifier's name.
2412     *  @param argtypes  The types of the invocation's value arguments.
2413     *  @param typeargtypes  The types of the invocation's type arguments.
2414     */
2415    Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
2416                                  Type site, Name name, List<Type> argtypes,
2417                                  List<Type> typeargtypes) {
2418        return resolveQualifiedMethod(pos, env, site.tsym, site, name, argtypes, typeargtypes);
2419    }
2420    Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
2421                                  Symbol location, Type site, Name name, List<Type> argtypes,
2422                                  List<Type> typeargtypes) {
2423        return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes);
2424    }
2425    private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext,
2426                                  DiagnosticPosition pos, Env<AttrContext> env,
2427                                  Symbol location, Type site, Name name, List<Type> argtypes,
2428                                  List<Type> typeargtypes) {
2429        return lookupMethod(env, pos, location, resolveContext, new BasicLookupHelper(name, site, argtypes, typeargtypes) {
2430            @Override
2431            Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2432                return findMethod(env, site, name, argtypes, typeargtypes,
2433                        phase.isBoxingRequired(),
2434                        phase.isVarargsRequired());
2435            }
2436            @Override
2437            Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2438                if (sym.kind.isResolutionError()) {
2439                    sym = super.access(env, pos, location, sym);
2440                } else if (allowMethodHandles) {
2441                    MethodSymbol msym = (MethodSymbol)sym;
2442                    if ((msym.flags() & SIGNATURE_POLYMORPHIC) != 0) {
2443                        return findPolymorphicSignatureInstance(env, sym, argtypes);
2444                    }
2445                }
2446                return sym;
2447            }
2448        });
2449    }
2450
2451    /** Find or create an implicit method of exactly the given type (after erasure).
2452     *  Searches in a side table, not the main scope of the site.
2453     *  This emulates the lookup process required by JSR 292 in JVM.
2454     *  @param env       Attribution environment
2455     *  @param spMethod  signature polymorphic method - i.e. MH.invokeExact
2456     *  @param argtypes  The required argument types
2457     */
2458    Symbol findPolymorphicSignatureInstance(Env<AttrContext> env,
2459                                            final Symbol spMethod,
2460                                            List<Type> argtypes) {
2461        Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
2462                (MethodSymbol)spMethod, currentResolutionContext, argtypes);
2463        for (Symbol sym : polymorphicSignatureScope.getSymbolsByName(spMethod.name)) {
2464            if (types.isSameType(mtype, sym.type)) {
2465               return sym;
2466            }
2467        }
2468
2469        // create the desired method
2470        long flags = ABSTRACT | HYPOTHETICAL | spMethod.flags() & Flags.AccessFlags;
2471        Symbol msym = new MethodSymbol(flags, spMethod.name, mtype, spMethod.owner) {
2472            @Override
2473            public Symbol baseSymbol() {
2474                return spMethod;
2475            }
2476        };
2477        if (!mtype.isErroneous()) { // Cache only if kosher.
2478            polymorphicSignatureScope.enter(msym);
2479        }
2480        return msym;
2481    }
2482
2483    /** Resolve a qualified method identifier, throw a fatal error if not
2484     *  found.
2485     *  @param pos       The position to use for error reporting.
2486     *  @param env       The environment current at the method invocation.
2487     *  @param site      The type of the qualifying expression, in which
2488     *                   identifier is searched.
2489     *  @param name      The identifier's name.
2490     *  @param argtypes  The types of the invocation's value arguments.
2491     *  @param typeargtypes  The types of the invocation's type arguments.
2492     */
2493    public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env,
2494                                        Type site, Name name,
2495                                        List<Type> argtypes,
2496                                        List<Type> typeargtypes) {
2497        MethodResolutionContext resolveContext = new MethodResolutionContext();
2498        resolveContext.internalResolution = true;
2499        Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym,
2500                site, name, argtypes, typeargtypes);
2501        if (sym.kind == MTH) return (MethodSymbol)sym;
2502        else throw new FatalError(
2503                 diags.fragment("fatal.err.cant.locate.meth",
2504                                name));
2505    }
2506
2507    /** Resolve constructor.
2508     *  @param pos       The position to use for error reporting.
2509     *  @param env       The environment current at the constructor invocation.
2510     *  @param site      The type of class for which a constructor is searched.
2511     *  @param argtypes  The types of the constructor invocation's value
2512     *                   arguments.
2513     *  @param typeargtypes  The types of the constructor invocation's type
2514     *                   arguments.
2515     */
2516    Symbol resolveConstructor(DiagnosticPosition pos,
2517                              Env<AttrContext> env,
2518                              Type site,
2519                              List<Type> argtypes,
2520                              List<Type> typeargtypes) {
2521        return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes);
2522    }
2523
2524    private Symbol resolveConstructor(MethodResolutionContext resolveContext,
2525                              final DiagnosticPosition pos,
2526                              Env<AttrContext> env,
2527                              Type site,
2528                              List<Type> argtypes,
2529                              List<Type> typeargtypes) {
2530        return lookupMethod(env, pos, site.tsym, resolveContext, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2531            @Override
2532            Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2533                return findConstructor(pos, env, site, argtypes, typeargtypes,
2534                        phase.isBoxingRequired(),
2535                        phase.isVarargsRequired());
2536            }
2537        });
2538    }
2539
2540    /** Resolve a constructor, throw a fatal error if not found.
2541     *  @param pos       The position to use for error reporting.
2542     *  @param env       The environment current at the method invocation.
2543     *  @param site      The type to be constructed.
2544     *  @param argtypes  The types of the invocation's value arguments.
2545     *  @param typeargtypes  The types of the invocation's type arguments.
2546     */
2547    public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2548                                        Type site,
2549                                        List<Type> argtypes,
2550                                        List<Type> typeargtypes) {
2551        MethodResolutionContext resolveContext = new MethodResolutionContext();
2552        resolveContext.internalResolution = true;
2553        Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
2554        if (sym.kind == MTH) return (MethodSymbol)sym;
2555        else throw new FatalError(
2556                 diags.fragment("fatal.err.cant.locate.ctor", site));
2557    }
2558
2559    Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2560                              Type site, List<Type> argtypes,
2561                              List<Type> typeargtypes,
2562                              boolean allowBoxing,
2563                              boolean useVarargs) {
2564        Symbol sym = findMethod(env, site,
2565                                    names.init, argtypes,
2566                                    typeargtypes, allowBoxing,
2567                                    useVarargs);
2568        chk.checkDeprecated(pos, env.info.scope.owner, sym);
2569        return sym;
2570    }
2571
2572    /** Resolve constructor using diamond inference.
2573     *  @param pos       The position to use for error reporting.
2574     *  @param env       The environment current at the constructor invocation.
2575     *  @param site      The type of class for which a constructor is searched.
2576     *                   The scope of this class has been touched in attribution.
2577     *  @param argtypes  The types of the constructor invocation's value
2578     *                   arguments.
2579     *  @param typeargtypes  The types of the constructor invocation's type
2580     *                   arguments.
2581     */
2582    Symbol resolveDiamond(DiagnosticPosition pos,
2583                              Env<AttrContext> env,
2584                              Type site,
2585                              List<Type> argtypes,
2586                              List<Type> typeargtypes) {
2587        return lookupMethod(env, pos, site.tsym, resolveMethodCheck,
2588                new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2589                    @Override
2590                    Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2591                        return findDiamond(env, site, argtypes, typeargtypes,
2592                                phase.isBoxingRequired(),
2593                                phase.isVarargsRequired());
2594                    }
2595                    @Override
2596                    Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2597                        if (sym.kind.isResolutionError()) {
2598                            if (sym.kind != WRONG_MTH &&
2599                                sym.kind != WRONG_MTHS) {
2600                                sym = super.access(env, pos, location, sym);
2601                            } else {
2602                                final JCDiagnostic details = sym.kind == WRONG_MTH ?
2603                                                ((InapplicableSymbolError)sym.baseSymbol()).errCandidate().snd :
2604                                                null;
2605                                sym = new DiamondError(sym, currentResolutionContext);
2606                                sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
2607                                env.info.pendingResolutionPhase = currentResolutionContext.step;
2608                            }
2609                        }
2610                        return sym;
2611                    }});
2612    }
2613
2614    /** This method scans all the constructor symbol in a given class scope -
2615     *  assuming that the original scope contains a constructor of the kind:
2616     *  {@code Foo(X x, Y y)}, where X,Y are class type-variables declared in Foo,
2617     *  a method check is executed against the modified constructor type:
2618     *  {@code <X,Y>Foo<X,Y>(X x, Y y)}. This is crucial in order to enable diamond
2619     *  inference. The inferred return type of the synthetic constructor IS
2620     *  the inferred type for the diamond operator.
2621     */
2622    private Symbol findDiamond(Env<AttrContext> env,
2623                              Type site,
2624                              List<Type> argtypes,
2625                              List<Type> typeargtypes,
2626                              boolean allowBoxing,
2627                              boolean useVarargs) {
2628        Symbol bestSoFar = methodNotFound;
2629        TypeSymbol tsym = site.tsym.isInterface() ? syms.objectType.tsym : site.tsym;
2630        for (final Symbol sym : tsym.members().getSymbolsByName(names.init)) {
2631            //- System.out.println(" e " + e.sym);
2632            if (sym.kind == MTH &&
2633                (sym.flags_field & SYNTHETIC) == 0) {
2634                    List<Type> oldParams = sym.type.hasTag(FORALL) ?
2635                            ((ForAll)sym.type).tvars :
2636                            List.<Type>nil();
2637                    Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
2638                                                 types.createMethodTypeWithReturn(sym.type.asMethodType(), site));
2639                    MethodSymbol newConstr = new MethodSymbol(sym.flags(), names.init, constrType, site.tsym) {
2640                        @Override
2641                        public Symbol baseSymbol() {
2642                            return sym;
2643                        }
2644                    };
2645                    bestSoFar = selectBest(env, site, argtypes, typeargtypes,
2646                            newConstr,
2647                            bestSoFar,
2648                            allowBoxing,
2649                            useVarargs);
2650            }
2651        }
2652        return bestSoFar;
2653    }
2654
2655    Symbol getMemberReference(DiagnosticPosition pos,
2656            Env<AttrContext> env,
2657            JCMemberReference referenceTree,
2658            Type site,
2659            Name name) {
2660
2661        site = types.capture(site);
2662
2663        ReferenceLookupHelper lookupHelper = makeReferenceLookupHelper(
2664                referenceTree, site, name, List.<Type>nil(), null, VARARITY);
2665
2666        Env<AttrContext> newEnv = env.dup(env.tree, env.info.dup());
2667        Symbol sym = lookupMethod(newEnv, env.tree.pos(), site.tsym,
2668                nilMethodCheck, lookupHelper);
2669
2670        env.info.pendingResolutionPhase = newEnv.info.pendingResolutionPhase;
2671
2672        return sym;
2673    }
2674
2675    ReferenceLookupHelper makeReferenceLookupHelper(JCMemberReference referenceTree,
2676                                  Type site,
2677                                  Name name,
2678                                  List<Type> argtypes,
2679                                  List<Type> typeargtypes,
2680                                  MethodResolutionPhase maxPhase) {
2681        if (!name.equals(names.init)) {
2682            //method reference
2683            return new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
2684        } else if (site.hasTag(ARRAY)) {
2685            //array constructor reference
2686            return new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
2687        } else {
2688            //class constructor reference
2689            return new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
2690        }
2691    }
2692
2693    /**
2694     * Resolution of member references is typically done as a single
2695     * overload resolution step, where the argument types A are inferred from
2696     * the target functional descriptor.
2697     *
2698     * If the member reference is a method reference with a type qualifier,
2699     * a two-step lookup process is performed. The first step uses the
2700     * expected argument list A, while the second step discards the first
2701     * type from A (which is treated as a receiver type).
2702     *
2703     * There are two cases in which inference is performed: (i) if the member
2704     * reference is a constructor reference and the qualifier type is raw - in
2705     * which case diamond inference is used to infer a parameterization for the
2706     * type qualifier; (ii) if the member reference is an unbound reference
2707     * where the type qualifier is raw - in that case, during the unbound lookup
2708     * the receiver argument type is used to infer an instantiation for the raw
2709     * qualifier type.
2710     *
2711     * When a multi-step resolution process is exploited, the process of picking
2712     * the resulting symbol is delegated to an helper class {@link com.sun.tools.javac.comp.Resolve.ReferenceChooser}.
2713     *
2714     * This routine returns a pair (T,S), where S is the member reference symbol,
2715     * and T is the type of the class in which S is defined. This is necessary as
2716     * the type T might be dynamically inferred (i.e. if constructor reference
2717     * has a raw qualifier).
2718     */
2719    Pair<Symbol, ReferenceLookupHelper> resolveMemberReference(Env<AttrContext> env,
2720                                  JCMemberReference referenceTree,
2721                                  Type site,
2722                                  Name name,
2723                                  List<Type> argtypes,
2724                                  List<Type> typeargtypes,
2725                                  MethodCheck methodCheck,
2726                                  InferenceContext inferenceContext,
2727                                  ReferenceChooser referenceChooser) {
2728
2729        //step 1 - bound lookup
2730        ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper(
2731                referenceTree, site, name, argtypes, typeargtypes, VARARITY);
2732        Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
2733        MethodResolutionContext boundSearchResolveContext = new MethodResolutionContext();
2734        boundSearchResolveContext.methodCheck = methodCheck;
2735        Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(),
2736                site.tsym, boundSearchResolveContext, boundLookupHelper);
2737        ReferenceLookupResult boundRes = new ReferenceLookupResult(boundSym, boundSearchResolveContext);
2738
2739        //step 2 - unbound lookup
2740        Symbol unboundSym = methodNotFound;
2741        Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
2742        ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext);
2743        ReferenceLookupResult unboundRes = referenceNotFound;
2744        if (unboundLookupHelper != null) {
2745            MethodResolutionContext unboundSearchResolveContext =
2746                    new MethodResolutionContext();
2747            unboundSearchResolveContext.methodCheck = methodCheck;
2748            unboundSym = lookupMethod(unboundEnv, env.tree.pos(),
2749                    site.tsym, unboundSearchResolveContext, unboundLookupHelper);
2750            unboundRes = new ReferenceLookupResult(unboundSym, unboundSearchResolveContext);
2751        }
2752
2753        //merge results
2754        Pair<Symbol, ReferenceLookupHelper> res;
2755        Symbol bestSym = referenceChooser.result(boundRes, unboundRes);
2756        res = new Pair<>(bestSym,
2757                bestSym == unboundSym ? unboundLookupHelper : boundLookupHelper);
2758        env.info.pendingResolutionPhase = bestSym == unboundSym ?
2759                unboundEnv.info.pendingResolutionPhase :
2760                boundEnv.info.pendingResolutionPhase;
2761
2762        return res;
2763    }
2764
2765    /**
2766     * This class is used to represent a method reference lookup result. It keeps track of two
2767     * things: (i) the symbol found during a method reference lookup and (ii) the static kind
2768     * of the lookup (see {@link com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind}).
2769     */
2770    static class ReferenceLookupResult {
2771
2772        /**
2773         * Static kind associated with a method reference lookup. Erroneous lookups end up with
2774         * the UNDEFINED kind; successful lookups will end up with either STATIC, NON_STATIC,
2775         * depending on whether all applicable candidates are static or non-static methods,
2776         * respectively. If a successful lookup has both static and non-static applicable methods,
2777         * its kind is set to BOTH.
2778         */
2779        enum StaticKind {
2780            STATIC,
2781            NON_STATIC,
2782            BOTH,
2783            UNDEFINED;
2784
2785            /**
2786             * Retrieve the static kind associated with a given (method) symbol.
2787             */
2788            static StaticKind from(Symbol s) {
2789                return s.isStatic() ?
2790                        STATIC : NON_STATIC;
2791            }
2792
2793            /**
2794             * Merge two static kinds together.
2795             */
2796            static StaticKind reduce(StaticKind sk1, StaticKind sk2) {
2797                if (sk1 == UNDEFINED) {
2798                    return sk2;
2799                } else if (sk2 == UNDEFINED) {
2800                    return sk1;
2801                } else {
2802                    return sk1 == sk2 ? sk1 : BOTH;
2803                }
2804            }
2805        }
2806
2807        /** The static kind. */
2808        StaticKind staticKind;
2809
2810        /** The lookup result. */
2811        Symbol sym;
2812
2813        ReferenceLookupResult(Symbol sym, MethodResolutionContext resolutionContext) {
2814            this.staticKind = staticKind(sym, resolutionContext);
2815            this.sym = sym;
2816        }
2817
2818        private StaticKind staticKind(Symbol sym, MethodResolutionContext resolutionContext) {
2819            switch (sym.kind) {
2820                case MTH:
2821                case AMBIGUOUS:
2822                    return resolutionContext.candidates.stream()
2823                            .filter(c -> c.isApplicable() && c.step == resolutionContext.step)
2824                            .map(c -> StaticKind.from(c.sym))
2825                            .reduce(StaticKind::reduce)
2826                            .orElse(StaticKind.UNDEFINED);
2827                default:
2828                    return StaticKind.UNDEFINED;
2829            }
2830        }
2831
2832        /**
2833         * Does this result corresponds to a successful lookup (i.e. one where a method has been found?)
2834         */
2835        boolean isSuccess() {
2836            return staticKind != StaticKind.UNDEFINED;
2837        }
2838
2839        /**
2840         * Does this result have given static kind?
2841         */
2842        boolean hasKind(StaticKind sk) {
2843            return this.staticKind == sk;
2844        }
2845
2846        /**
2847         * Error recovery helper: can this lookup result be ignored (for the purpose of returning
2848         * some 'better' result) ?
2849         */
2850        boolean canIgnore() {
2851            switch (sym.kind) {
2852                case ABSENT_MTH:
2853                    return true;
2854                case WRONG_MTH:
2855                    InapplicableSymbolError errSym =
2856                            (InapplicableSymbolError)sym.baseSymbol();
2857                    return new Template(MethodCheckDiag.ARITY_MISMATCH.regex())
2858                            .matches(errSym.errCandidate().snd);
2859                case WRONG_MTHS:
2860                    InapplicableSymbolsError errSyms =
2861                            (InapplicableSymbolsError)sym.baseSymbol();
2862                    return errSyms.filterCandidates(errSyms.mapCandidates()).isEmpty();
2863                default:
2864                    return false;
2865            }
2866        }
2867    }
2868
2869    /**
2870     * This abstract class embodies the logic that converts one (bound lookup) or two (unbound lookup)
2871     * {@code ReferenceLookupResult} objects into a (@code Symbol), which is then regarded as the
2872     * result of method reference resolution.
2873     */
2874    abstract class ReferenceChooser {
2875        /**
2876         * Generate a result from a pair of lookup result objects. This method delegates to the
2877         * appropriate result generation routine.
2878         */
2879        Symbol result(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
2880            return unboundRes != referenceNotFound ?
2881                    unboundResult(boundRes, unboundRes) :
2882                    boundResult(boundRes);
2883        }
2884
2885        /**
2886         * Generate a symbol from a given bound lookup result.
2887         */
2888        abstract Symbol boundResult(ReferenceLookupResult boundRes);
2889
2890        /**
2891         * Generate a symbol from a pair of bound/unbound lookup results.
2892         */
2893        abstract Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes);
2894    }
2895
2896    /**
2897     * This chooser implements the selection strategy used during a full lookup; this logic
2898     * is described in JLS SE 8 (15.3.2).
2899     */
2900    ReferenceChooser basicReferenceChooser = new ReferenceChooser() {
2901
2902        @Override
2903        Symbol boundResult(ReferenceLookupResult boundRes) {
2904            return !boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC) ?
2905                    boundRes.sym : //the search produces a non-static method
2906                    new BadMethodReferenceError(boundRes.sym, false);
2907        }
2908
2909        @Override
2910        Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
2911            if (boundRes.hasKind(StaticKind.STATIC) &&
2912                    (!unboundRes.isSuccess() || unboundRes.hasKind(StaticKind.STATIC))) {
2913                //the first search produces a static method and no non-static method is applicable
2914                //during the second search
2915                return boundRes.sym;
2916            } else if (unboundRes.hasKind(StaticKind.NON_STATIC) &&
2917                    (!boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC))) {
2918                //the second search produces a non-static method and no static method is applicable
2919                //during the first search
2920                return unboundRes.sym;
2921            } else if (boundRes.isSuccess() && unboundRes.isSuccess()) {
2922                //both searches produce some result; ambiguity (error recovery)
2923                return ambiguityError(boundRes.sym, unboundRes.sym);
2924            } else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
2925                //Both searches failed to produce a result with correct staticness (i.e. first search
2926                //produces an non-static method). Alternatively, a given search produced a result
2927                //with the right staticness, but the other search has applicable methods with wrong
2928                //staticness (error recovery)
2929                return new BadMethodReferenceError(boundRes.isSuccess() ? boundRes.sym : unboundRes.sym, true);
2930            } else {
2931                //both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
2932                return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
2933                        unboundRes.sym : boundRes.sym;
2934            }
2935        }
2936    };
2937
2938    /**
2939     * This chooser implements the selection strategy used during an arity-based lookup; this logic
2940     * is described in JLS SE 8 (15.12.2.1).
2941     */
2942    ReferenceChooser structuralReferenceChooser = new ReferenceChooser() {
2943
2944        @Override
2945        Symbol boundResult(ReferenceLookupResult boundRes) {
2946            return (!boundRes.isSuccess() || !boundRes.hasKind(StaticKind.STATIC)) ?
2947                    boundRes.sym : //the search has at least one applicable non-static method
2948                    new BadMethodReferenceError(boundRes.sym, false);
2949        }
2950
2951        @Override
2952        Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
2953            if (boundRes.isSuccess() && !boundRes.hasKind(StaticKind.NON_STATIC)) {
2954                //the first serach has at least one applicable static method
2955                return boundRes.sym;
2956            } else if (unboundRes.isSuccess() && !unboundRes.hasKind(StaticKind.STATIC)) {
2957                //the second search has at least one applicable non-static method
2958                return unboundRes.sym;
2959            } else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
2960                //either the first search produces a non-static method, or second search produces
2961                //a non-static method (error recovery)
2962                return new BadMethodReferenceError(boundRes.isSuccess() ? boundRes.sym : unboundRes.sym, true);
2963            } else {
2964                //both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
2965                return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
2966                        unboundRes.sym : boundRes.sym;
2967            }
2968        }
2969    };
2970
2971    /**
2972     * Helper for defining custom method-like lookup logic; a lookup helper
2973     * provides hooks for (i) the actual lookup logic and (ii) accessing the
2974     * lookup result (this step might result in compiler diagnostics to be generated)
2975     */
2976    abstract class LookupHelper {
2977
2978        /** name of the symbol to lookup */
2979        Name name;
2980
2981        /** location in which the lookup takes place */
2982        Type site;
2983
2984        /** actual types used during the lookup */
2985        List<Type> argtypes;
2986
2987        /** type arguments used during the lookup */
2988        List<Type> typeargtypes;
2989
2990        /** Max overload resolution phase handled by this helper */
2991        MethodResolutionPhase maxPhase;
2992
2993        LookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2994            this.name = name;
2995            this.site = site;
2996            this.argtypes = argtypes;
2997            this.typeargtypes = typeargtypes;
2998            this.maxPhase = maxPhase;
2999        }
3000
3001        /**
3002         * Should lookup stop at given phase with given result
3003         */
3004        final boolean shouldStop(Symbol sym, MethodResolutionPhase phase) {
3005            return phase.ordinal() > maxPhase.ordinal() ||
3006                !sym.kind.isResolutionError() || sym.kind == AMBIGUOUS;
3007        }
3008
3009        /**
3010         * Search for a symbol under a given overload resolution phase - this method
3011         * is usually called several times, once per each overload resolution phase
3012         */
3013        abstract Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase);
3014
3015        /**
3016         * Dump overload resolution info
3017         */
3018        void debug(DiagnosticPosition pos, Symbol sym) {
3019            //do nothing
3020        }
3021
3022        /**
3023         * Validate the result of the lookup
3024         */
3025        abstract Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym);
3026    }
3027
3028    abstract class BasicLookupHelper extends LookupHelper {
3029
3030        BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) {
3031            this(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY);
3032        }
3033
3034        BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3035            super(name, site, argtypes, typeargtypes, maxPhase);
3036        }
3037
3038        @Override
3039        final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3040            Symbol sym = doLookup(env, phase);
3041            if (sym.kind == AMBIGUOUS) {
3042                AmbiguityError a_err = (AmbiguityError)sym.baseSymbol();
3043                sym = a_err.mergeAbstracts(site);
3044            }
3045            return sym;
3046        }
3047
3048        abstract Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase);
3049
3050        @Override
3051        Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3052            if (sym.kind.isResolutionError()) {
3053                //if nothing is found return the 'first' error
3054                sym = accessMethod(sym, pos, location, site, name, true, argtypes, typeargtypes);
3055            }
3056            return sym;
3057        }
3058
3059        @Override
3060        void debug(DiagnosticPosition pos, Symbol sym) {
3061            reportVerboseResolutionDiagnostic(pos, name, site, argtypes, typeargtypes, sym);
3062        }
3063    }
3064
3065    /**
3066     * Helper class for member reference lookup. A reference lookup helper
3067     * defines the basic logic for member reference lookup; a method gives
3068     * access to an 'unbound' helper used to perform an unbound member
3069     * reference lookup.
3070     */
3071    abstract class ReferenceLookupHelper extends LookupHelper {
3072
3073        /** The member reference tree */
3074        JCMemberReference referenceTree;
3075
3076        ReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3077                List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3078            super(name, site, argtypes, typeargtypes, maxPhase);
3079            this.referenceTree = referenceTree;
3080        }
3081
3082        /**
3083         * Returns an unbound version of this lookup helper. By default, this
3084         * method returns an dummy lookup helper.
3085         */
3086        ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3087            return null;
3088        }
3089
3090        /**
3091         * Get the kind of the member reference
3092         */
3093        abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym);
3094
3095        Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3096            if (sym.kind == AMBIGUOUS) {
3097                AmbiguityError a_err = (AmbiguityError)sym.baseSymbol();
3098                sym = a_err.mergeAbstracts(site);
3099            }
3100            //skip error reporting
3101            return sym;
3102        }
3103    }
3104
3105    /**
3106     * Helper class for method reference lookup. The lookup logic is based
3107     * upon Resolve.findMethod; in certain cases, this helper class has a
3108     * corresponding unbound helper class (see UnboundMethodReferenceLookupHelper).
3109     * In such cases, non-static lookup results are thrown away.
3110     */
3111    class MethodReferenceLookupHelper extends ReferenceLookupHelper {
3112
3113        /** The original method reference lookup site. */
3114        Type originalSite;
3115
3116        MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3117                List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3118            super(referenceTree, name, types.skipTypeVars(site, true), argtypes, typeargtypes, maxPhase);
3119            this.originalSite = site;
3120        }
3121
3122        @Override
3123        final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3124            return findMethod(env, site, name, argtypes, typeargtypes,
3125                    phase.isBoxingRequired(), phase.isVarargsRequired());
3126        }
3127
3128        @Override
3129        ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3130            if (TreeInfo.isStaticSelector(referenceTree.expr, names)) {
3131                if (argtypes.nonEmpty() &&
3132                        (argtypes.head.hasTag(NONE) ||
3133                        types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), site))) {
3134                    return new UnboundMethodReferenceLookupHelper(referenceTree, name,
3135                            originalSite, argtypes, typeargtypes, maxPhase);
3136                } else {
3137                    return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
3138                        @Override
3139                        ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3140                            return this;
3141                        }
3142
3143                        @Override
3144                        Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3145                            return methodNotFound;
3146                        }
3147
3148                        @Override
3149                        ReferenceKind referenceKind(Symbol sym) {
3150                            Assert.error();
3151                            return null;
3152                        }
3153                    };
3154                }
3155            } else {
3156                return super.unboundLookup(inferenceContext);
3157            }
3158        }
3159
3160        @Override
3161        ReferenceKind referenceKind(Symbol sym) {
3162            if (sym.isStatic()) {
3163                return ReferenceKind.STATIC;
3164            } else {
3165                Name selName = TreeInfo.name(referenceTree.getQualifierExpression());
3166                return selName != null && selName == names._super ?
3167                        ReferenceKind.SUPER :
3168                        ReferenceKind.BOUND;
3169            }
3170        }
3171    }
3172
3173    /**
3174     * Helper class for unbound method reference lookup. Essentially the same
3175     * as the basic method reference lookup helper; main difference is that static
3176     * lookup results are thrown away. If qualifier type is raw, an attempt to
3177     * infer a parameterized type is made using the first actual argument (that
3178     * would otherwise be ignored during the lookup).
3179     */
3180    class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper {
3181
3182        UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3183                List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3184            super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase);
3185            if (site.isRaw() && !argtypes.head.hasTag(NONE)) {
3186                Type asSuperSite = types.asSuper(argtypes.head, site.tsym);
3187                this.site = types.skipTypeVars(asSuperSite, true);
3188            }
3189        }
3190
3191        @Override
3192        ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3193            return this;
3194        }
3195
3196        @Override
3197        ReferenceKind referenceKind(Symbol sym) {
3198            return ReferenceKind.UNBOUND;
3199        }
3200    }
3201
3202    /**
3203     * Helper class for array constructor lookup; an array constructor lookup
3204     * is simulated by looking up a method that returns the array type specified
3205     * as qualifier, and that accepts a single int parameter (size of the array).
3206     */
3207    class ArrayConstructorReferenceLookupHelper extends ReferenceLookupHelper {
3208
3209        ArrayConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
3210                List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3211            super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
3212        }
3213
3214        @Override
3215        protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3216            WriteableScope sc = WriteableScope.create(syms.arrayClass);
3217            MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym);
3218            arrayConstr.type = new MethodType(List.<Type>of(syms.intType), site, List.<Type>nil(), syms.methodClass);
3219            sc.enter(arrayConstr);
3220            return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false);
3221        }
3222
3223        @Override
3224        ReferenceKind referenceKind(Symbol sym) {
3225            return ReferenceKind.ARRAY_CTOR;
3226        }
3227    }
3228
3229    /**
3230     * Helper class for constructor reference lookup. The lookup logic is based
3231     * upon either Resolve.findMethod or Resolve.findDiamond - depending on
3232     * whether the constructor reference needs diamond inference (this is the case
3233     * if the qualifier type is raw). A special erroneous symbol is returned
3234     * if the lookup returns the constructor of an inner class and there's no
3235     * enclosing instance in scope.
3236     */
3237    class ConstructorReferenceLookupHelper extends ReferenceLookupHelper {
3238
3239        boolean needsInference;
3240
3241        ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
3242                List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3243            super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
3244            if (site.isRaw()) {
3245                this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym, site.getMetadata());
3246                needsInference = true;
3247            }
3248        }
3249
3250        @Override
3251        protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3252            Symbol sym = needsInference ?
3253                findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
3254                findMethod(env, site, name, argtypes, typeargtypes,
3255                        phase.isBoxingRequired(), phase.isVarargsRequired());
3256            return enclosingInstanceMissing(env, site) ? new BadConstructorReferenceError(sym) : sym;
3257        }
3258
3259        @Override
3260        ReferenceKind referenceKind(Symbol sym) {
3261            return site.getEnclosingType().hasTag(NONE) ?
3262                    ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER;
3263        }
3264    }
3265
3266    /**
3267     * Main overload resolution routine. On each overload resolution step, a
3268     * lookup helper class is used to perform the method/constructor lookup;
3269     * at the end of the lookup, the helper is used to validate the results
3270     * (this last step might trigger overload resolution diagnostics).
3271     */
3272    Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, MethodCheck methodCheck, LookupHelper lookupHelper) {
3273        MethodResolutionContext resolveContext = new MethodResolutionContext();
3274        resolveContext.methodCheck = methodCheck;
3275        return lookupMethod(env, pos, location, resolveContext, lookupHelper);
3276    }
3277
3278    Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location,
3279            MethodResolutionContext resolveContext, LookupHelper lookupHelper) {
3280        MethodResolutionContext prevResolutionContext = currentResolutionContext;
3281        try {
3282            Symbol bestSoFar = methodNotFound;
3283            currentResolutionContext = resolveContext;
3284            for (MethodResolutionPhase phase : methodResolutionSteps) {
3285                if (lookupHelper.shouldStop(bestSoFar, phase))
3286                    break;
3287                MethodResolutionPhase prevPhase = currentResolutionContext.step;
3288                Symbol prevBest = bestSoFar;
3289                currentResolutionContext.step = phase;
3290                Symbol sym = lookupHelper.lookup(env, phase);
3291                lookupHelper.debug(pos, sym);
3292                bestSoFar = phase.mergeResults(bestSoFar, sym);
3293                env.info.pendingResolutionPhase = (prevBest == bestSoFar) ? prevPhase : phase;
3294            }
3295            return lookupHelper.access(env, pos, location, bestSoFar);
3296        } finally {
3297            currentResolutionContext = prevResolutionContext;
3298        }
3299    }
3300
3301    /**
3302     * Resolve `c.name' where name == this or name == super.
3303     * @param pos           The position to use for error reporting.
3304     * @param env           The environment current at the expression.
3305     * @param c             The qualifier.
3306     * @param name          The identifier's name.
3307     */
3308    Symbol resolveSelf(DiagnosticPosition pos,
3309                       Env<AttrContext> env,
3310                       TypeSymbol c,
3311                       Name name) {
3312        Env<AttrContext> env1 = env;
3313        boolean staticOnly = false;
3314        while (env1.outer != null) {
3315            if (isStatic(env1)) staticOnly = true;
3316            if (env1.enclClass.sym == c) {
3317                Symbol sym = env1.info.scope.findFirst(name);
3318                if (sym != null) {
3319                    if (staticOnly) sym = new StaticError(sym);
3320                    return accessBase(sym, pos, env.enclClass.sym.type,
3321                                  name, true);
3322                }
3323            }
3324            if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3325            env1 = env1.outer;
3326        }
3327        if (c.isInterface() &&
3328            name == names._super && !isStatic(env) &&
3329            types.isDirectSuperInterface(c, env.enclClass.sym)) {
3330            //this might be a default super call if one of the superinterfaces is 'c'
3331            for (Type t : pruneInterfaces(env.enclClass.type)) {
3332                if (t.tsym == c) {
3333                    env.info.defaultSuperCallSite = t;
3334                    return new VarSymbol(0, names._super,
3335                            types.asSuper(env.enclClass.type, c), env.enclClass.sym);
3336                }
3337            }
3338            //find a direct superinterface that is a subtype of 'c'
3339            for (Type i : types.interfaces(env.enclClass.type)) {
3340                if (i.tsym.isSubClass(c, types) && i.tsym != c) {
3341                    log.error(pos, "illegal.default.super.call", c,
3342                            diags.fragment("redundant.supertype", c, i));
3343                    return syms.errSymbol;
3344                }
3345            }
3346            Assert.error();
3347        }
3348        log.error(pos, "not.encl.class", c);
3349        return syms.errSymbol;
3350    }
3351    //where
3352    private List<Type> pruneInterfaces(Type t) {
3353        ListBuffer<Type> result = new ListBuffer<>();
3354        for (Type t1 : types.interfaces(t)) {
3355            boolean shouldAdd = true;
3356            for (Type t2 : types.interfaces(t)) {
3357                if (t1 != t2 && types.isSubtypeNoCapture(t2, t1)) {
3358                    shouldAdd = false;
3359                }
3360            }
3361            if (shouldAdd) {
3362                result.append(t1);
3363            }
3364        }
3365        return result.toList();
3366    }
3367
3368
3369    /**
3370     * Resolve `c.this' for an enclosing class c that contains the
3371     * named member.
3372     * @param pos           The position to use for error reporting.
3373     * @param env           The environment current at the expression.
3374     * @param member        The member that must be contained in the result.
3375     */
3376    Symbol resolveSelfContaining(DiagnosticPosition pos,
3377                                 Env<AttrContext> env,
3378                                 Symbol member,
3379                                 boolean isSuperCall) {
3380        Symbol sym = resolveSelfContainingInternal(env, member, isSuperCall);
3381        if (sym == null) {
3382            log.error(pos, "encl.class.required", member);
3383            return syms.errSymbol;
3384        } else {
3385            return accessBase(sym, pos, env.enclClass.sym.type, sym.name, true);
3386        }
3387    }
3388
3389    boolean enclosingInstanceMissing(Env<AttrContext> env, Type type) {
3390        if (type.hasTag(CLASS) && type.getEnclosingType().hasTag(CLASS)) {
3391            Symbol encl = resolveSelfContainingInternal(env, type.tsym, false);
3392            return encl == null || encl.kind.isResolutionError();
3393        }
3394        return false;
3395    }
3396
3397    private Symbol resolveSelfContainingInternal(Env<AttrContext> env,
3398                                 Symbol member,
3399                                 boolean isSuperCall) {
3400        Name name = names._this;
3401        Env<AttrContext> env1 = isSuperCall ? env.outer : env;
3402        boolean staticOnly = false;
3403        if (env1 != null) {
3404            while (env1 != null && env1.outer != null) {
3405                if (isStatic(env1)) staticOnly = true;
3406                if (env1.enclClass.sym.isSubClass(member.owner.enclClass(), types)) {
3407                    Symbol sym = env1.info.scope.findFirst(name);
3408                    if (sym != null) {
3409                        if (staticOnly) sym = new StaticError(sym);
3410                        return sym;
3411                    }
3412                }
3413                if ((env1.enclClass.sym.flags() & STATIC) != 0)
3414                    staticOnly = true;
3415                env1 = env1.outer;
3416            }
3417        }
3418        return null;
3419    }
3420
3421    /**
3422     * Resolve an appropriate implicit this instance for t's container.
3423     * JLS 8.8.5.1 and 15.9.2
3424     */
3425    Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) {
3426        return resolveImplicitThis(pos, env, t, false);
3427    }
3428
3429    Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t, boolean isSuperCall) {
3430        Type thisType = (t.tsym.owner.kind.matches(KindSelector.VAL_MTH)
3431                         ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this)
3432                         : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type;
3433        if (env.info.isSelfCall && thisType.tsym == env.enclClass.sym)
3434            log.error(pos, "cant.ref.before.ctor.called", "this");
3435        return thisType;
3436    }
3437
3438/* ***************************************************************************
3439 *  ResolveError classes, indicating error situations when accessing symbols
3440 ****************************************************************************/
3441
3442    //used by TransTypes when checking target type of synthetic cast
3443    public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
3444        AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
3445        logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
3446    }
3447    //where
3448    private void logResolveError(ResolveError error,
3449            DiagnosticPosition pos,
3450            Symbol location,
3451            Type site,
3452            Name name,
3453            List<Type> argtypes,
3454            List<Type> typeargtypes) {
3455        JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
3456                pos, location, site, name, argtypes, typeargtypes);
3457        if (d != null) {
3458            d.setFlag(DiagnosticFlag.RESOLVE_ERROR);
3459            log.report(d);
3460        }
3461    }
3462
3463    private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
3464
3465    public Object methodArguments(List<Type> argtypes) {
3466        if (argtypes == null || argtypes.isEmpty()) {
3467            return noArgs;
3468        } else {
3469            ListBuffer<Object> diagArgs = new ListBuffer<>();
3470            for (Type t : argtypes) {
3471                if (t.hasTag(DEFERRED)) {
3472                    diagArgs.append(((DeferredAttr.DeferredType)t).tree);
3473                } else {
3474                    diagArgs.append(t);
3475                }
3476            }
3477            return diagArgs;
3478        }
3479    }
3480
3481    /**
3482     * Root class for resolution errors. Subclass of ResolveError
3483     * represent a different kinds of resolution error - as such they must
3484     * specify how they map into concrete compiler diagnostics.
3485     */
3486    abstract class ResolveError extends Symbol {
3487
3488        /** The name of the kind of error, for debugging only. */
3489        final String debugName;
3490
3491        ResolveError(Kind kind, String debugName) {
3492            super(kind, 0, null, null, null);
3493            this.debugName = debugName;
3494        }
3495
3496        @Override @DefinedBy(Api.LANGUAGE_MODEL)
3497        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
3498            throw new AssertionError();
3499        }
3500
3501        @Override
3502        public String toString() {
3503            return debugName;
3504        }
3505
3506        @Override
3507        public boolean exists() {
3508            return false;
3509        }
3510
3511        @Override
3512        public boolean isStatic() {
3513            return false;
3514        }
3515
3516        /**
3517         * Create an external representation for this erroneous symbol to be
3518         * used during attribution - by default this returns the symbol of a
3519         * brand new error type which stores the original type found
3520         * during resolution.
3521         *
3522         * @param name     the name used during resolution
3523         * @param location the location from which the symbol is accessed
3524         */
3525        protected Symbol access(Name name, TypeSymbol location) {
3526            return types.createErrorType(name, location, syms.errSymbol.type).tsym;
3527        }
3528
3529        /**
3530         * Create a diagnostic representing this resolution error.
3531         *
3532         * @param dkind     The kind of the diagnostic to be created (e.g error).
3533         * @param pos       The position to be used for error reporting.
3534         * @param site      The original type from where the selection took place.
3535         * @param name      The name of the symbol to be resolved.
3536         * @param argtypes  The invocation's value arguments,
3537         *                  if we looked for a method.
3538         * @param typeargtypes  The invocation's type arguments,
3539         *                      if we looked for a method.
3540         */
3541        abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3542                DiagnosticPosition pos,
3543                Symbol location,
3544                Type site,
3545                Name name,
3546                List<Type> argtypes,
3547                List<Type> typeargtypes);
3548    }
3549
3550    /**
3551     * This class is the root class of all resolution errors caused by
3552     * an invalid symbol being found during resolution.
3553     */
3554    abstract class InvalidSymbolError extends ResolveError {
3555
3556        /** The invalid symbol found during resolution */
3557        Symbol sym;
3558
3559        InvalidSymbolError(Kind kind, Symbol sym, String debugName) {
3560            super(kind, debugName);
3561            this.sym = sym;
3562        }
3563
3564        @Override
3565        public boolean exists() {
3566            return true;
3567        }
3568
3569        @Override
3570        public String toString() {
3571             return super.toString() + " wrongSym=" + sym;
3572        }
3573
3574        @Override
3575        public Symbol access(Name name, TypeSymbol location) {
3576            if (!sym.kind.isResolutionError() && sym.kind.matches(KindSelector.TYP))
3577                return types.createErrorType(name, location, sym.type).tsym;
3578            else
3579                return sym;
3580        }
3581    }
3582
3583    /**
3584     * InvalidSymbolError error class indicating that a symbol matching a
3585     * given name does not exists in a given site.
3586     */
3587    class SymbolNotFoundError extends ResolveError {
3588
3589        SymbolNotFoundError(Kind kind) {
3590            this(kind, "symbol not found error");
3591        }
3592
3593        SymbolNotFoundError(Kind kind, String debugName) {
3594            super(kind, debugName);
3595        }
3596
3597        @Override
3598        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3599                DiagnosticPosition pos,
3600                Symbol location,
3601                Type site,
3602                Name name,
3603                List<Type> argtypes,
3604                List<Type> typeargtypes) {
3605            argtypes = argtypes == null ? List.<Type>nil() : argtypes;
3606            typeargtypes = typeargtypes == null ? List.<Type>nil() : typeargtypes;
3607            if (name == names.error)
3608                return null;
3609
3610            boolean hasLocation = false;
3611            if (location == null) {
3612                location = site.tsym;
3613            }
3614            if (!location.name.isEmpty()) {
3615                if (location.kind == PCK && !site.tsym.exists()) {
3616                    return diags.create(dkind, log.currentSource(), pos,
3617                        "doesnt.exist", location);
3618                }
3619                hasLocation = !location.name.equals(names._this) &&
3620                        !location.name.equals(names._super);
3621            }
3622            boolean isConstructor = name == names.init;
3623            KindName kindname = isConstructor ? KindName.CONSTRUCTOR : kind.absentKind();
3624            Name idname = isConstructor ? site.tsym.name : name;
3625            String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
3626            if (hasLocation) {
3627                return diags.create(dkind, log.currentSource(), pos,
3628                        errKey, kindname, idname, //symbol kindname, name
3629                        typeargtypes, args(argtypes), //type parameters and arguments (if any)
3630                        getLocationDiag(location, site)); //location kindname, type
3631            }
3632            else {
3633                return diags.create(dkind, log.currentSource(), pos,
3634                        errKey, kindname, idname, //symbol kindname, name
3635                        typeargtypes, args(argtypes)); //type parameters and arguments (if any)
3636            }
3637        }
3638        //where
3639        private Object args(List<Type> args) {
3640            return args.isEmpty() ? args : methodArguments(args);
3641        }
3642
3643        private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) {
3644            String key = "cant.resolve";
3645            String suffix = hasLocation ? ".location" : "";
3646            switch (kindname) {
3647                case METHOD:
3648                case CONSTRUCTOR: {
3649                    suffix += ".args";
3650                    suffix += hasTypeArgs ? ".params" : "";
3651                }
3652            }
3653            return key + suffix;
3654        }
3655        private JCDiagnostic getLocationDiag(Symbol location, Type site) {
3656            if (location.kind == VAR) {
3657                return diags.fragment("location.1",
3658                    kindName(location),
3659                    location,
3660                    location.type);
3661            } else {
3662                return diags.fragment("location",
3663                    typeKindName(site),
3664                    site,
3665                    null);
3666            }
3667        }
3668    }
3669
3670    /**
3671     * InvalidSymbolError error class indicating that a given symbol
3672     * (either a method, a constructor or an operand) is not applicable
3673     * given an actual arguments/type argument list.
3674     */
3675    class InapplicableSymbolError extends ResolveError {
3676
3677        protected MethodResolutionContext resolveContext;
3678
3679        InapplicableSymbolError(MethodResolutionContext context) {
3680            this(WRONG_MTH, "inapplicable symbol error", context);
3681        }
3682
3683        protected InapplicableSymbolError(Kind kind, String debugName, MethodResolutionContext context) {
3684            super(kind, debugName);
3685            this.resolveContext = context;
3686        }
3687
3688        @Override
3689        public String toString() {
3690            return super.toString();
3691        }
3692
3693        @Override
3694        public boolean exists() {
3695            return true;
3696        }
3697
3698        @Override
3699        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3700                DiagnosticPosition pos,
3701                Symbol location,
3702                Type site,
3703                Name name,
3704                List<Type> argtypes,
3705                List<Type> typeargtypes) {
3706            if (name == names.error)
3707                return null;
3708
3709            Pair<Symbol, JCDiagnostic> c = errCandidate();
3710            if (compactMethodDiags) {
3711                JCDiagnostic simpleDiag =
3712                    MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd);
3713                if (simpleDiag != null) {
3714                    return simpleDiag;
3715                }
3716            }
3717            Symbol ws = c.fst.asMemberOf(site, types);
3718            return diags.create(dkind, log.currentSource(), pos,
3719                      "cant.apply.symbol",
3720                      kindName(ws),
3721                      ws.name == names.init ? ws.owner.name : ws.name,
3722                      methodArguments(ws.type.getParameterTypes()),
3723                      methodArguments(argtypes),
3724                      kindName(ws.owner),
3725                      ws.owner.type,
3726                      c.snd);
3727        }
3728
3729        @Override
3730        public Symbol access(Name name, TypeSymbol location) {
3731            return types.createErrorType(name, location, syms.errSymbol.type).tsym;
3732        }
3733
3734        protected Pair<Symbol, JCDiagnostic> errCandidate() {
3735            Candidate bestSoFar = null;
3736            for (Candidate c : resolveContext.candidates) {
3737                if (c.isApplicable()) continue;
3738                bestSoFar = c;
3739            }
3740            Assert.checkNonNull(bestSoFar);
3741            return new Pair<>(bestSoFar.sym, bestSoFar.details);
3742        }
3743    }
3744
3745    /**
3746     * ResolveError error class indicating that a symbol (either methods, constructors or operand)
3747     * is not applicable given an actual arguments/type argument list.
3748     */
3749    class InapplicableSymbolsError extends InapplicableSymbolError {
3750
3751        InapplicableSymbolsError(MethodResolutionContext context) {
3752            super(WRONG_MTHS, "inapplicable symbols", context);
3753        }
3754
3755        @Override
3756        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3757                DiagnosticPosition pos,
3758                Symbol location,
3759                Type site,
3760                Name name,
3761                List<Type> argtypes,
3762                List<Type> typeargtypes) {
3763            Map<Symbol, JCDiagnostic> candidatesMap = mapCandidates();
3764            Map<Symbol, JCDiagnostic> filteredCandidates = compactMethodDiags ?
3765                    filterCandidates(candidatesMap) :
3766                    mapCandidates();
3767            if (filteredCandidates.isEmpty()) {
3768                filteredCandidates = candidatesMap;
3769            }
3770            boolean truncatedDiag = candidatesMap.size() != filteredCandidates.size();
3771            if (filteredCandidates.size() > 1) {
3772                JCDiagnostic err = diags.create(dkind,
3773                        null,
3774                        truncatedDiag ?
3775                            EnumSet.of(DiagnosticFlag.COMPRESSED) :
3776                            EnumSet.noneOf(DiagnosticFlag.class),
3777                        log.currentSource(),
3778                        pos,
3779                        "cant.apply.symbols",
3780                        name == names.init ? KindName.CONSTRUCTOR : kind.absentKind(),
3781                        name == names.init ? site.tsym.name : name,
3782                        methodArguments(argtypes));
3783                return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(filteredCandidates, site));
3784            } else if (filteredCandidates.size() == 1) {
3785                Map.Entry<Symbol, JCDiagnostic> _e =
3786                                filteredCandidates.entrySet().iterator().next();
3787                final Pair<Symbol, JCDiagnostic> p = new Pair<>(_e.getKey(), _e.getValue());
3788                JCDiagnostic d = new InapplicableSymbolError(resolveContext) {
3789                    @Override
3790                    protected Pair<Symbol, JCDiagnostic> errCandidate() {
3791                        return p;
3792                    }
3793                }.getDiagnostic(dkind, pos,
3794                    location, site, name, argtypes, typeargtypes);
3795                if (truncatedDiag) {
3796                    d.setFlag(DiagnosticFlag.COMPRESSED);
3797                }
3798                return d;
3799            } else {
3800                return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
3801                    location, site, name, argtypes, typeargtypes);
3802            }
3803        }
3804        //where
3805            private Map<Symbol, JCDiagnostic> mapCandidates() {
3806                Map<Symbol, JCDiagnostic> candidates = new LinkedHashMap<>();
3807                for (Candidate c : resolveContext.candidates) {
3808                    if (c.isApplicable()) continue;
3809                    candidates.put(c.sym, c.details);
3810                }
3811                return candidates;
3812            }
3813
3814            Map<Symbol, JCDiagnostic> filterCandidates(Map<Symbol, JCDiagnostic> candidatesMap) {
3815                Map<Symbol, JCDiagnostic> candidates = new LinkedHashMap<>();
3816                for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) {
3817                    JCDiagnostic d = _entry.getValue();
3818                    if (!new Template(MethodCheckDiag.ARITY_MISMATCH.regex()).matches(d)) {
3819                        candidates.put(_entry.getKey(), d);
3820                    }
3821                }
3822                return candidates;
3823            }
3824
3825            private List<JCDiagnostic> candidateDetails(Map<Symbol, JCDiagnostic> candidatesMap, Type site) {
3826                List<JCDiagnostic> details = List.nil();
3827                for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) {
3828                    Symbol sym = _entry.getKey();
3829                    JCDiagnostic detailDiag = diags.fragment("inapplicable.method",
3830                            Kinds.kindName(sym),
3831                            sym.location(site, types),
3832                            sym.asMemberOf(site, types),
3833                            _entry.getValue());
3834                    details = details.prepend(detailDiag);
3835                }
3836                //typically members are visited in reverse order (see Scope)
3837                //so we need to reverse the candidate list so that candidates
3838                //conform to source order
3839                return details;
3840            }
3841    }
3842
3843    /**
3844     * DiamondError error class indicating that a constructor symbol is not applicable
3845     * given an actual arguments/type argument list using diamond inference.
3846     */
3847    class DiamondError extends InapplicableSymbolError {
3848
3849        Symbol sym;
3850
3851        public DiamondError(Symbol sym, MethodResolutionContext context) {
3852            super(sym.kind, "diamondError", context);
3853            this.sym = sym;
3854        }
3855
3856        JCDiagnostic getDetails() {
3857            return (sym.kind == WRONG_MTH) ?
3858                    ((InapplicableSymbolError)sym.baseSymbol()).errCandidate().snd :
3859                    null;
3860        }
3861
3862        @Override
3863        JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
3864                Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
3865            JCDiagnostic details = getDetails();
3866            if (details != null && compactMethodDiags) {
3867                JCDiagnostic simpleDiag =
3868                        MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, details);
3869                if (simpleDiag != null) {
3870                    return simpleDiag;
3871                }
3872            }
3873            String key = details == null ?
3874                "cant.apply.diamond" :
3875                "cant.apply.diamond.1";
3876            return diags.create(dkind, log.currentSource(), pos, key,
3877                    diags.fragment("diamond", site.tsym), details);
3878        }
3879    }
3880
3881    /**
3882     * An InvalidSymbolError error class indicating that a symbol is not
3883     * accessible from a given site
3884     */
3885    class AccessError extends InvalidSymbolError {
3886
3887        private Env<AttrContext> env;
3888        private Type site;
3889
3890        AccessError(Symbol sym) {
3891            this(null, null, sym);
3892        }
3893
3894        AccessError(Env<AttrContext> env, Type site, Symbol sym) {
3895            super(HIDDEN, sym, "access error");
3896            this.env = env;
3897            this.site = site;
3898        }
3899
3900        @Override
3901        public boolean exists() {
3902            return false;
3903        }
3904
3905        @Override
3906        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3907                DiagnosticPosition pos,
3908                Symbol location,
3909                Type site,
3910                Name name,
3911                List<Type> argtypes,
3912                List<Type> typeargtypes) {
3913            if (sym.owner.type.hasTag(ERROR))
3914                return null;
3915
3916            if (sym.name == names.init && sym.owner != site.tsym) {
3917                return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind,
3918                        pos, location, site, name, argtypes, typeargtypes);
3919            }
3920            else if ((sym.flags() & PUBLIC) != 0
3921                || (env != null && this.site != null
3922                    && !isAccessible(env, this.site))) {
3923                return diags.create(dkind, log.currentSource(),
3924                        pos, "not.def.access.class.intf.cant.access",
3925                    sym, sym.location());
3926            }
3927            else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) {
3928                return diags.create(dkind, log.currentSource(),
3929                        pos, "report.access", sym,
3930                        asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
3931                        sym.location());
3932            }
3933            else {
3934                return diags.create(dkind, log.currentSource(),
3935                        pos, "not.def.public.cant.access", sym, sym.location());
3936            }
3937        }
3938    }
3939
3940    /**
3941     * InvalidSymbolError error class indicating that an instance member
3942     * has erroneously been accessed from a static context.
3943     */
3944    class StaticError extends InvalidSymbolError {
3945
3946        StaticError(Symbol sym) {
3947            super(STATICERR, sym, "static error");
3948        }
3949
3950        @Override
3951        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3952                DiagnosticPosition pos,
3953                Symbol location,
3954                Type site,
3955                Name name,
3956                List<Type> argtypes,
3957                List<Type> typeargtypes) {
3958            Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS))
3959                ? types.erasure(sym.type).tsym
3960                : sym);
3961            return diags.create(dkind, log.currentSource(), pos,
3962                    "non-static.cant.be.ref", kindName(sym), errSym);
3963        }
3964    }
3965
3966    /**
3967     * InvalidSymbolError error class indicating that a pair of symbols
3968     * (either methods, constructors or operands) are ambiguous
3969     * given an actual arguments/type argument list.
3970     */
3971    class AmbiguityError extends ResolveError {
3972
3973        /** The other maximally specific symbol */
3974        List<Symbol> ambiguousSyms = List.nil();
3975
3976        @Override
3977        public boolean exists() {
3978            return true;
3979        }
3980
3981        AmbiguityError(Symbol sym1, Symbol sym2) {
3982            super(AMBIGUOUS, "ambiguity error");
3983            ambiguousSyms = flatten(sym2).appendList(flatten(sym1));
3984        }
3985
3986        private List<Symbol> flatten(Symbol sym) {
3987            if (sym.kind == AMBIGUOUS) {
3988                return ((AmbiguityError)sym.baseSymbol()).ambiguousSyms;
3989            } else {
3990                return List.of(sym);
3991            }
3992        }
3993
3994        AmbiguityError addAmbiguousSymbol(Symbol s) {
3995            ambiguousSyms = ambiguousSyms.prepend(s);
3996            return this;
3997        }
3998
3999        @Override
4000        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4001                DiagnosticPosition pos,
4002                Symbol location,
4003                Type site,
4004                Name name,
4005                List<Type> argtypes,
4006                List<Type> typeargtypes) {
4007            List<Symbol> diagSyms = ambiguousSyms.reverse();
4008            Symbol s1 = diagSyms.head;
4009            Symbol s2 = diagSyms.tail.head;
4010            Name sname = s1.name;
4011            if (sname == names.init) sname = s1.owner.name;
4012            return diags.create(dkind, log.currentSource(),
4013                    pos, "ref.ambiguous", sname,
4014                    kindName(s1),
4015                    s1,
4016                    s1.location(site, types),
4017                    kindName(s2),
4018                    s2,
4019                    s2.location(site, types));
4020        }
4021
4022        /**
4023         * If multiple applicable methods are found during overload and none of them
4024         * is more specific than the others, attempt to merge their signatures.
4025         */
4026        Symbol mergeAbstracts(Type site) {
4027            List<Symbol> ambiguousInOrder = ambiguousSyms.reverse();
4028            for (Symbol s : ambiguousInOrder) {
4029                Type mt = types.memberType(site, s);
4030                boolean found = true;
4031                List<Type> allThrown = mt.getThrownTypes();
4032                for (Symbol s2 : ambiguousInOrder) {
4033                    Type mt2 = types.memberType(site, s2);
4034                    if ((s2.flags() & ABSTRACT) == 0 ||
4035                        !types.overrideEquivalent(mt, mt2) ||
4036                        !types.isSameTypes(s.erasure(types).getParameterTypes(),
4037                                       s2.erasure(types).getParameterTypes())) {
4038                        //ambiguity cannot be resolved
4039                        return this;
4040                    }
4041                    Type mst = mostSpecificReturnType(mt, mt2);
4042                    if (mst == null || mst != mt) {
4043                        found = false;
4044                        break;
4045                    }
4046                    allThrown = chk.intersect(allThrown, mt2.getThrownTypes());
4047                }
4048                if (found) {
4049                    //all ambiguous methods were abstract and one method had
4050                    //most specific return type then others
4051                    return (allThrown == mt.getThrownTypes()) ?
4052                            s : new MethodSymbol(
4053                                s.flags(),
4054                                s.name,
4055                                types.createMethodTypeWithThrown(s.type, allThrown),
4056                                s.owner);
4057                }
4058            }
4059            return this;
4060        }
4061
4062        @Override
4063        protected Symbol access(Name name, TypeSymbol location) {
4064            Symbol firstAmbiguity = ambiguousSyms.last();
4065            return firstAmbiguity.kind == TYP ?
4066                    types.createErrorType(name, location, firstAmbiguity.type).tsym :
4067                    firstAmbiguity;
4068        }
4069    }
4070
4071    class BadVarargsMethod extends ResolveError {
4072
4073        ResolveError delegatedError;
4074
4075        BadVarargsMethod(ResolveError delegatedError) {
4076            super(delegatedError.kind, "badVarargs");
4077            this.delegatedError = delegatedError;
4078        }
4079
4080        @Override
4081        public Symbol baseSymbol() {
4082            return delegatedError.baseSymbol();
4083        }
4084
4085        @Override
4086        protected Symbol access(Name name, TypeSymbol location) {
4087            return delegatedError.access(name, location);
4088        }
4089
4090        @Override
4091        public boolean exists() {
4092            return true;
4093        }
4094
4095        @Override
4096        JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4097            return delegatedError.getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes);
4098        }
4099    }
4100
4101    /**
4102     * BadMethodReferenceError error class indicating that a method reference symbol has been found,
4103     * but with the wrong staticness.
4104     */
4105    class BadMethodReferenceError extends StaticError {
4106
4107        boolean unboundLookup;
4108
4109        public BadMethodReferenceError(Symbol sym, boolean unboundLookup) {
4110            super(sym);
4111            this.unboundLookup = unboundLookup;
4112        }
4113
4114        @Override
4115        JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4116            final String key;
4117            if (!unboundLookup) {
4118                key = "bad.static.method.in.bound.lookup";
4119            } else if (sym.isStatic()) {
4120                key = "bad.static.method.in.unbound.lookup";
4121            } else {
4122                key = "bad.instance.method.in.unbound.lookup";
4123            }
4124            return sym.kind.isResolutionError() ?
4125                    ((ResolveError)sym).getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes) :
4126                    diags.create(dkind, log.currentSource(), pos, key, Kinds.kindName(sym), sym);
4127        }
4128    }
4129
4130    /**
4131     * BadConstructorReferenceError error class indicating that a constructor reference symbol has been found,
4132     * but pointing to a class for which an enclosing instance is not available.
4133     */
4134    class BadConstructorReferenceError extends InvalidSymbolError {
4135
4136        public BadConstructorReferenceError(Symbol sym) {
4137            super(MISSING_ENCL, sym, "BadConstructorReferenceError");
4138        }
4139
4140        @Override
4141        JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4142           return diags.create(dkind, log.currentSource(), pos,
4143                "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType());
4144        }
4145    }
4146
4147    /**
4148     * Helper class for method resolution diagnostic simplification.
4149     * Certain resolution diagnostic are rewritten as simpler diagnostic
4150     * where the enclosing resolution diagnostic (i.e. 'inapplicable method')
4151     * is stripped away, as it doesn't carry additional info. The logic
4152     * for matching a given diagnostic is given in terms of a template
4153     * hierarchy: a diagnostic template can be specified programmatically,
4154     * so that only certain diagnostics are matched. Each templete is then
4155     * associated with a rewriter object that carries out the task of rewtiting
4156     * the diagnostic to a simpler one.
4157     */
4158    static class MethodResolutionDiagHelper {
4159
4160        /**
4161         * A diagnostic rewriter transforms a method resolution diagnostic
4162         * into a simpler one
4163         */
4164        interface DiagnosticRewriter {
4165            JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
4166                    DiagnosticPosition preferedPos, DiagnosticSource preferredSource,
4167                    DiagnosticType preferredKind, JCDiagnostic d);
4168        }
4169
4170        /**
4171         * A diagnostic template is made up of two ingredients: (i) a regular
4172         * expression for matching a diagnostic key and (ii) a list of sub-templates
4173         * for matching diagnostic arguments.
4174         */
4175        static class Template {
4176
4177            /** regex used to match diag key */
4178            String regex;
4179
4180            /** templates used to match diagnostic args */
4181            Template[] subTemplates;
4182
4183            Template(String key, Template... subTemplates) {
4184                this.regex = key;
4185                this.subTemplates = subTemplates;
4186            }
4187
4188            /**
4189             * Returns true if the regex matches the diagnostic key and if
4190             * all diagnostic arguments are matches by corresponding sub-templates.
4191             */
4192            boolean matches(Object o) {
4193                JCDiagnostic d = (JCDiagnostic)o;
4194                Object[] args = d.getArgs();
4195                if (!d.getCode().matches(regex) ||
4196                        subTemplates.length != d.getArgs().length) {
4197                    return false;
4198                }
4199                for (int i = 0; i < args.length ; i++) {
4200                    if (!subTemplates[i].matches(args[i])) {
4201                        return false;
4202                    }
4203                }
4204                return true;
4205            }
4206        }
4207
4208        /**
4209         * Common rewriter for all argument mismatch simplifications.
4210         */
4211        static class ArgMismatchRewriter implements DiagnosticRewriter {
4212
4213            /** the index of the subdiagnostic to be used as primary. */
4214            int causeIndex;
4215
4216            public ArgMismatchRewriter(int causeIndex) {
4217                this.causeIndex = causeIndex;
4218            }
4219
4220            @Override
4221            public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
4222                    DiagnosticPosition preferedPos, DiagnosticSource preferredSource,
4223                    DiagnosticType preferredKind, JCDiagnostic d) {
4224                JCDiagnostic cause = (JCDiagnostic)d.getArgs()[causeIndex];
4225                DiagnosticPosition pos = d.getDiagnosticPosition();
4226                if (pos == null) {
4227                    pos = preferedPos;
4228                }
4229                return diags.create(preferredKind, preferredSource, pos,
4230                        "prob.found.req", cause);
4231            }
4232        }
4233
4234        /** a dummy template that match any diagnostic argument */
4235        static final Template skip = new Template("") {
4236            @Override
4237            boolean matches(Object d) {
4238                return true;
4239            }
4240        };
4241
4242        /** template for matching inference-free arguments mismatch failures */
4243        static final Template argMismatchTemplate = new Template(MethodCheckDiag.ARG_MISMATCH.regex(), skip);
4244
4245        /** template for matching inference related arguments mismatch failures */
4246        static final Template inferArgMismatchTemplate = new Template(MethodCheckDiag.ARG_MISMATCH.regex(), skip, skip) {
4247            @Override
4248            boolean matches(Object o) {
4249                if (!super.matches(o)) {
4250                    return false;
4251                }
4252                JCDiagnostic d = (JCDiagnostic)o;
4253                @SuppressWarnings("unchecked")
4254                List<Type> tvars = (List<Type>)d.getArgs()[0];
4255                return !containsAny(d, tvars);
4256            }
4257
4258            BiPredicate<Object, List<Type>> containsPredicate = (o, ts) -> {
4259                if (o instanceof Type) {
4260                    return ((Type)o).containsAny(ts);
4261                } else if (o instanceof JCDiagnostic) {
4262                    return containsAny((JCDiagnostic)o, ts);
4263                } else {
4264                    return false;
4265                }
4266            };
4267
4268            boolean containsAny(JCDiagnostic d, List<Type> ts) {
4269                return Stream.of(d.getArgs())
4270                        .anyMatch(o -> containsPredicate.test(o, ts));
4271            }
4272        };
4273
4274        /** rewriter map used for method resolution simplification */
4275        static final Map<Template, DiagnosticRewriter> rewriters = new LinkedHashMap<>();
4276
4277        static {
4278            rewriters.put(argMismatchTemplate, new ArgMismatchRewriter(0));
4279            rewriters.put(inferArgMismatchTemplate, new ArgMismatchRewriter(1));
4280        }
4281
4282        /**
4283         * Main entry point for diagnostic rewriting - given a diagnostic, see if any templates matches it,
4284         * and rewrite it accordingly.
4285         */
4286        static JCDiagnostic rewrite(JCDiagnostic.Factory diags, DiagnosticPosition pos, DiagnosticSource source,
4287                                    DiagnosticType dkind, JCDiagnostic d) {
4288            for (Map.Entry<Template, DiagnosticRewriter> _entry : rewriters.entrySet()) {
4289                if (_entry.getKey().matches(d)) {
4290                    JCDiagnostic simpleDiag =
4291                            _entry.getValue().rewriteDiagnostic(diags, pos, source, dkind, d);
4292                    simpleDiag.setFlag(DiagnosticFlag.COMPRESSED);
4293                    return simpleDiag;
4294                }
4295            }
4296            return null;
4297        }
4298    }
4299
4300    enum MethodResolutionPhase {
4301        BASIC(false, false),
4302        BOX(true, false),
4303        VARARITY(true, true) {
4304            @Override
4305            public Symbol mergeResults(Symbol bestSoFar, Symbol sym) {
4306                //Check invariants (see {@code LookupHelper.shouldStop})
4307                Assert.check(bestSoFar.kind.isResolutionError() && bestSoFar.kind != AMBIGUOUS);
4308                if (!sym.kind.isResolutionError()) {
4309                    //varargs resolution successful
4310                    return sym;
4311                } else {
4312                    //pick best error
4313                    switch (bestSoFar.kind) {
4314                        case WRONG_MTH:
4315                        case WRONG_MTHS:
4316                            //Override previous errors if they were caused by argument mismatch.
4317                            //This generally means preferring current symbols - but we need to pay
4318                            //attention to the fact that the varargs lookup returns 'less' candidates
4319                            //than the previous rounds, and adjust that accordingly.
4320                            switch (sym.kind) {
4321                                case WRONG_MTH:
4322                                    //if the previous round matched more than one method, return that
4323                                    //result instead
4324                                    return bestSoFar.kind == WRONG_MTHS ?
4325                                            bestSoFar : sym;
4326                                case ABSENT_MTH:
4327                                    //do not override erroneous symbol if the arity lookup did not
4328                                    //match any method
4329                                    return bestSoFar;
4330                                case WRONG_MTHS:
4331                                default:
4332                                    //safe to override
4333                                    return sym;
4334                            }
4335                        default:
4336                            //otherwise, return first error
4337                            return bestSoFar;
4338                    }
4339                }
4340            }
4341        };
4342
4343        final boolean isBoxingRequired;
4344        final boolean isVarargsRequired;
4345
4346        MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) {
4347           this.isBoxingRequired = isBoxingRequired;
4348           this.isVarargsRequired = isVarargsRequired;
4349        }
4350
4351        public boolean isBoxingRequired() {
4352            return isBoxingRequired;
4353        }
4354
4355        public boolean isVarargsRequired() {
4356            return isVarargsRequired;
4357        }
4358
4359        public Symbol mergeResults(Symbol prev, Symbol sym) {
4360            return sym;
4361        }
4362    }
4363
4364    final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
4365
4366    /**
4367     * A resolution context is used to keep track of intermediate results of
4368     * overload resolution, such as list of method that are not applicable
4369     * (used to generate more precise diagnostics) and so on. Resolution contexts
4370     * can be nested - this means that when each overload resolution routine should
4371     * work within the resolution context it created.
4372     */
4373    class MethodResolutionContext {
4374
4375        private List<Candidate> candidates = List.nil();
4376
4377        MethodResolutionPhase step = null;
4378
4379        MethodCheck methodCheck = resolveMethodCheck;
4380
4381        private boolean internalResolution = false;
4382        private DeferredAttr.AttrMode attrMode = DeferredAttr.AttrMode.SPECULATIVE;
4383
4384        void addInapplicableCandidate(Symbol sym, JCDiagnostic details) {
4385            Candidate c = new Candidate(currentResolutionContext.step, sym, details, null);
4386            candidates = candidates.append(c);
4387        }
4388
4389        void addApplicableCandidate(Symbol sym, Type mtype) {
4390            Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype);
4391            candidates = candidates.append(c);
4392        }
4393
4394        DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext, ResultInfo pendingResult, Warner warn) {
4395            DeferredAttrContext parent = (pendingResult == null)
4396                ? deferredAttr.emptyDeferredAttrContext
4397                : pendingResult.checkContext.deferredAttrContext();
4398            return deferredAttr.new DeferredAttrContext(attrMode, sym, step,
4399                    inferenceContext, parent, warn);
4400        }
4401
4402        /**
4403         * This class represents an overload resolution candidate. There are two
4404         * kinds of candidates: applicable methods and inapplicable methods;
4405         * applicable methods have a pointer to the instantiated method type,
4406         * while inapplicable candidates contain further details about the
4407         * reason why the method has been considered inapplicable.
4408         */
4409        @SuppressWarnings("overrides")
4410        class Candidate {
4411
4412            final MethodResolutionPhase step;
4413            final Symbol sym;
4414            final JCDiagnostic details;
4415            final Type mtype;
4416
4417            private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
4418                this.step = step;
4419                this.sym = sym;
4420                this.details = details;
4421                this.mtype = mtype;
4422            }
4423
4424            @Override
4425            public boolean equals(Object o) {
4426                if (o instanceof Candidate) {
4427                    Symbol s1 = this.sym;
4428                    Symbol s2 = ((Candidate)o).sym;
4429                    if  ((s1 != s2 &&
4430                            (s1.overrides(s2, s1.owner.type.tsym, types, false) ||
4431                            (s2.overrides(s1, s2.owner.type.tsym, types, false)))) ||
4432                            ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner))
4433                        return true;
4434                }
4435                return false;
4436            }
4437
4438            boolean isApplicable() {
4439                return mtype != null;
4440            }
4441        }
4442
4443        DeferredAttr.AttrMode attrMode() {
4444            return attrMode;
4445        }
4446
4447        boolean internal() {
4448            return internalResolution;
4449        }
4450    }
4451
4452    MethodResolutionContext currentResolutionContext = null;
4453}
4454