Resolve.java revision 2646:ff1998c1ecab
1/*
2 * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.tools.javac.comp;
27
28import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
29import com.sun.tools.javac.api.Formattable.LocalizedString;
30import com.sun.tools.javac.code.*;
31import com.sun.tools.javac.code.Scope.WriteableScope;
32import com.sun.tools.javac.code.Symbol.*;
33import com.sun.tools.javac.code.Type.*;
34import com.sun.tools.javac.comp.Attr.ResultInfo;
35import com.sun.tools.javac.comp.Check.CheckContext;
36import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
37import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
38import com.sun.tools.javac.comp.DeferredAttr.DeferredType;
39import com.sun.tools.javac.comp.Infer.InferenceContext;
40import com.sun.tools.javac.comp.Infer.FreeTypeListener;
41import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
42import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.DiagnosticRewriter;
43import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template;
44import com.sun.tools.javac.jvm.*;
45import com.sun.tools.javac.main.Option;
46import com.sun.tools.javac.tree.*;
47import com.sun.tools.javac.tree.JCTree.*;
48import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
49import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
50import com.sun.tools.javac.util.*;
51import com.sun.tools.javac.util.DefinedBy.Api;
52import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
53import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
54import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
55
56import java.util.Arrays;
57import java.util.Collection;
58import java.util.EnumSet;
59import java.util.Iterator;
60import java.util.LinkedHashMap;
61import java.util.Map;
62
63import javax.lang.model.element.ElementVisitor;
64
65import static com.sun.tools.javac.code.Flags.*;
66import static com.sun.tools.javac.code.Flags.BLOCK;
67import static com.sun.tools.javac.code.Kinds.*;
68import static com.sun.tools.javac.code.Kinds.ERRONEOUS;
69import static com.sun.tools.javac.code.TypeTag.*;
70import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
71import static com.sun.tools.javac.tree.JCTree.Tag.*;
72
73/** Helper class for name resolution, used mostly by the attribution phase.
74 *
75 *  <p><b>This is NOT part of any supported API.
76 *  If you write code that depends on this, you do so at your own risk.
77 *  This code and its internal interfaces are subject to change or
78 *  deletion without notice.</b>
79 */
80public class Resolve {
81    protected static final Context.Key<Resolve> resolveKey = new Context.Key<>();
82
83    Names names;
84    Log log;
85    Symtab syms;
86    Attr attr;
87    DeferredAttr deferredAttr;
88    Check chk;
89    Infer infer;
90    ClassFinder finder;
91    TreeInfo treeinfo;
92    Types types;
93    JCDiagnostic.Factory diags;
94    public final boolean allowMethodHandles;
95    public final boolean allowFunctionalInterfaceMostSpecific;
96    public final boolean checkVarargsAccessAfterResolution;
97    private final boolean debugResolve;
98    private final boolean compactMethodDiags;
99    final EnumSet<VerboseResolutionMode> verboseResolutionMode;
100
101    WriteableScope polymorphicSignatureScope;
102
103    protected Resolve(Context context) {
104        context.put(resolveKey, this);
105        syms = Symtab.instance(context);
106
107        varNotFound = new
108            SymbolNotFoundError(ABSENT_VAR);
109        methodNotFound = new
110            SymbolNotFoundError(ABSENT_MTH);
111        methodWithCorrectStaticnessNotFound = new
112            SymbolNotFoundError(WRONG_STATICNESS,
113                "method found has incorrect staticness");
114        typeNotFound = new
115            SymbolNotFoundError(ABSENT_TYP);
116
117        names = Names.instance(context);
118        log = Log.instance(context);
119        attr = Attr.instance(context);
120        deferredAttr = DeferredAttr.instance(context);
121        chk = Check.instance(context);
122        infer = Infer.instance(context);
123        finder = ClassFinder.instance(context);
124        treeinfo = TreeInfo.instance(context);
125        types = Types.instance(context);
126        diags = JCDiagnostic.Factory.instance(context);
127        Source source = Source.instance(context);
128        Options options = Options.instance(context);
129        debugResolve = options.isSet("debugresolve");
130        compactMethodDiags = options.isSet(Option.XDIAGS, "compact") ||
131                options.isUnset(Option.XDIAGS) && options.isUnset("rawDiagnostics");
132        verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
133        Target target = Target.instance(context);
134        allowMethodHandles = target.hasMethodHandles();
135        allowFunctionalInterfaceMostSpecific = source.allowFunctionalInterfaceMostSpecific();
136        checkVarargsAccessAfterResolution =
137                source.allowPostApplicabilityVarargsAccessCheck();
138        polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
139
140        inapplicableMethodException = new InapplicableMethodException(diags);
141    }
142
143    /** error symbols, which are returned when resolution fails
144     */
145    private final SymbolNotFoundError varNotFound;
146    private final SymbolNotFoundError methodNotFound;
147    private final SymbolNotFoundError methodWithCorrectStaticnessNotFound;
148    private final SymbolNotFoundError typeNotFound;
149
150    public static Resolve instance(Context context) {
151        Resolve instance = context.get(resolveKey);
152        if (instance == null)
153            instance = new Resolve(context);
154        return instance;
155    }
156
157    // <editor-fold defaultstate="collapsed" desc="Verbose resolution diagnostics support">
158    enum VerboseResolutionMode {
159        SUCCESS("success"),
160        FAILURE("failure"),
161        APPLICABLE("applicable"),
162        INAPPLICABLE("inapplicable"),
163        DEFERRED_INST("deferred-inference"),
164        PREDEF("predef"),
165        OBJECT_INIT("object-init"),
166        INTERNAL("internal");
167
168        final String opt;
169
170        private VerboseResolutionMode(String opt) {
171            this.opt = opt;
172        }
173
174        static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) {
175            String s = opts.get("verboseResolution");
176            EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class);
177            if (s == null) return res;
178            if (s.contains("all")) {
179                res = EnumSet.allOf(VerboseResolutionMode.class);
180            }
181            Collection<String> args = Arrays.asList(s.split(","));
182            for (VerboseResolutionMode mode : values()) {
183                if (args.contains(mode.opt)) {
184                    res.add(mode);
185                } else if (args.contains("-" + mode.opt)) {
186                    res.remove(mode);
187                }
188            }
189            return res;
190        }
191    }
192
193    void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site,
194            List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) {
195        boolean success = bestSoFar.kind < ERRONEOUS;
196
197        if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) {
198            return;
199        } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) {
200            return;
201        }
202
203        if (bestSoFar.name == names.init &&
204                bestSoFar.owner == syms.objectType.tsym &&
205                !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) {
206            return; //skip diags for Object constructor resolution
207        } else if (site == syms.predefClass.type &&
208                !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) {
209            return; //skip spurious diags for predef symbols (i.e. operators)
210        } else if (currentResolutionContext.internalResolution &&
211                !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) {
212            return;
213        }
214
215        int pos = 0;
216        int mostSpecificPos = -1;
217        ListBuffer<JCDiagnostic> subDiags = new ListBuffer<>();
218        for (Candidate c : currentResolutionContext.candidates) {
219            if (currentResolutionContext.step != c.step ||
220                    (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) ||
221                    (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) {
222                continue;
223            } else {
224                subDiags.append(c.isApplicable() ?
225                        getVerboseApplicableCandidateDiag(pos, c.sym, c.mtype) :
226                        getVerboseInapplicableCandidateDiag(pos, c.sym, c.details));
227                if (c.sym == bestSoFar)
228                    mostSpecificPos = pos;
229                pos++;
230            }
231        }
232        String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1";
233        List<Type> argtypes2 = Type.map(argtypes,
234                    deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, bestSoFar, currentResolutionContext.step));
235        JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name,
236                site.tsym, mostSpecificPos, currentResolutionContext.step,
237                methodArguments(argtypes2),
238                methodArguments(typeargtypes));
239        JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList());
240        log.report(d);
241    }
242
243    JCDiagnostic getVerboseApplicableCandidateDiag(int pos, Symbol sym, Type inst) {
244        JCDiagnostic subDiag = null;
245        if (sym.type.hasTag(FORALL)) {
246            subDiag = diags.fragment("partial.inst.sig", inst);
247        }
248
249        String key = subDiag == null ?
250                "applicable.method.found" :
251                "applicable.method.found.1";
252
253        return diags.fragment(key, pos, sym, subDiag);
254    }
255
256    JCDiagnostic getVerboseInapplicableCandidateDiag(int pos, Symbol sym, JCDiagnostic subDiag) {
257        return diags.fragment("not.applicable.method.found", pos, sym, subDiag);
258    }
259    // </editor-fold>
260
261/* ************************************************************************
262 * Identifier resolution
263 *************************************************************************/
264
265    /** An environment is "static" if its static level is greater than
266     *  the one of its outer environment
267     */
268    protected static boolean isStatic(Env<AttrContext> env) {
269        return env.outer != null && env.info.staticLevel > env.outer.info.staticLevel;
270    }
271
272    /** An environment is an "initializer" if it is a constructor or
273     *  an instance initializer.
274     */
275    static boolean isInitializer(Env<AttrContext> env) {
276        Symbol owner = env.info.scope.owner;
277        return owner.isConstructor() ||
278            owner.owner.kind == TYP &&
279            (owner.kind == VAR ||
280             owner.kind == MTH && (owner.flags() & BLOCK) != 0) &&
281            (owner.flags() & STATIC) == 0;
282    }
283
284    /** Is class accessible in given evironment?
285     *  @param env    The current environment.
286     *  @param c      The class whose accessibility is checked.
287     */
288    public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) {
289        return isAccessible(env, c, false);
290    }
291
292    public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) {
293        boolean isAccessible = false;
294        switch ((short)(c.flags() & AccessFlags)) {
295            case PRIVATE:
296                isAccessible =
297                    env.enclClass.sym.outermostClass() ==
298                    c.owner.outermostClass();
299                break;
300            case 0:
301                isAccessible =
302                    env.toplevel.packge == c.owner // fast special case
303                    ||
304                    env.toplevel.packge == c.packge()
305                    ||
306                    // Hack: this case is added since synthesized default constructors
307                    // of anonymous classes should be allowed to access
308                    // classes which would be inaccessible otherwise.
309                    env.enclMethod != null &&
310                    (env.enclMethod.mods.flags & ANONCONSTR) != 0;
311                break;
312            default: // error recovery
313            case PUBLIC:
314                isAccessible = true;
315                break;
316            case PROTECTED:
317                isAccessible =
318                    env.toplevel.packge == c.owner // fast special case
319                    ||
320                    env.toplevel.packge == c.packge()
321                    ||
322                    isInnerSubClass(env.enclClass.sym, c.owner);
323                break;
324        }
325        return (checkInner == false || c.type.getEnclosingType() == Type.noType) ?
326            isAccessible :
327            isAccessible && isAccessible(env, c.type.getEnclosingType(), checkInner);
328    }
329    //where
330        /** Is given class a subclass of given base class, or an inner class
331         *  of a subclass?
332         *  Return null if no such class exists.
333         *  @param c     The class which is the subclass or is contained in it.
334         *  @param base  The base class
335         */
336        private boolean isInnerSubClass(ClassSymbol c, Symbol base) {
337            while (c != null && !c.isSubClass(base, types)) {
338                c = c.owner.enclClass();
339            }
340            return c != null;
341        }
342
343    boolean isAccessible(Env<AttrContext> env, Type t) {
344        return isAccessible(env, t, false);
345    }
346
347    boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) {
348        return (t.hasTag(ARRAY))
349            ? isAccessible(env, types.cvarUpperBound(types.elemtype(t)))
350            : isAccessible(env, t.tsym, checkInner);
351    }
352
353    /** Is symbol accessible as a member of given type in given environment?
354     *  @param env    The current environment.
355     *  @param site   The type of which the tested symbol is regarded
356     *                as a member.
357     *  @param sym    The symbol.
358     */
359    public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) {
360        return isAccessible(env, site, sym, false);
361    }
362    public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) {
363        if (sym.name == names.init && sym.owner != site.tsym) return false;
364        switch ((short)(sym.flags() & AccessFlags)) {
365        case PRIVATE:
366            return
367                (env.enclClass.sym == sym.owner // fast special case
368                 ||
369                 env.enclClass.sym.outermostClass() ==
370                 sym.owner.outermostClass())
371                &&
372                sym.isInheritedIn(site.tsym, types);
373        case 0:
374            return
375                (env.toplevel.packge == sym.owner.owner // fast special case
376                 ||
377                 env.toplevel.packge == sym.packge())
378                &&
379                isAccessible(env, site, checkInner)
380                &&
381                sym.isInheritedIn(site.tsym, types)
382                &&
383                notOverriddenIn(site, sym);
384        case PROTECTED:
385            return
386                (env.toplevel.packge == sym.owner.owner // fast special case
387                 ||
388                 env.toplevel.packge == sym.packge()
389                 ||
390                 isProtectedAccessible(sym, env.enclClass.sym, site)
391                 ||
392                 // OK to select instance method or field from 'super' or type name
393                 // (but type names should be disallowed elsewhere!)
394                 env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP)
395                &&
396                isAccessible(env, site, checkInner)
397                &&
398                notOverriddenIn(site, sym);
399        default: // this case includes erroneous combinations as well
400            return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym);
401        }
402    }
403    //where
404    /* `sym' is accessible only if not overridden by
405     * another symbol which is a member of `site'
406     * (because, if it is overridden, `sym' is not strictly
407     * speaking a member of `site'). A polymorphic signature method
408     * cannot be overridden (e.g. MH.invokeExact(Object[])).
409     */
410    private boolean notOverriddenIn(Type site, Symbol sym) {
411        if (sym.kind != MTH || sym.isConstructor() || sym.isStatic())
412            return true;
413        else {
414            Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true);
415            return (s2 == null || s2 == sym || sym.owner == s2.owner ||
416                    !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
417        }
418    }
419    //where
420        /** Is given protected symbol accessible if it is selected from given site
421         *  and the selection takes place in given class?
422         *  @param sym     The symbol with protected access
423         *  @param c       The class where the access takes place
424         *  @site          The type of the qualifier
425         */
426        private
427        boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) {
428            Type newSite = site.hasTag(TYPEVAR) ? site.getUpperBound() : site;
429            while (c != null &&
430                   !(c.isSubClass(sym.owner, types) &&
431                     (c.flags() & INTERFACE) == 0 &&
432                     // In JLS 2e 6.6.2.1, the subclass restriction applies
433                     // only to instance fields and methods -- types are excluded
434                     // regardless of whether they are declared 'static' or not.
435                     ((sym.flags() & STATIC) != 0 || sym.kind == TYP || newSite.tsym.isSubClass(c, types))))
436                c = c.owner.enclClass();
437            return c != null;
438        }
439
440    /**
441     * Performs a recursive scan of a type looking for accessibility problems
442     * from current attribution environment
443     */
444    void checkAccessibleType(Env<AttrContext> env, Type t) {
445        accessibilityChecker.visit(t, env);
446    }
447
448    /**
449     * Accessibility type-visitor
450     */
451    Types.SimpleVisitor<Void, Env<AttrContext>> accessibilityChecker =
452            new Types.SimpleVisitor<Void, Env<AttrContext>>() {
453
454        void visit(List<Type> ts, Env<AttrContext> env) {
455            for (Type t : ts) {
456                visit(t, env);
457            }
458        }
459
460        public Void visitType(Type t, Env<AttrContext> env) {
461            return null;
462        }
463
464        @Override
465        public Void visitArrayType(ArrayType t, Env<AttrContext> env) {
466            visit(t.elemtype, env);
467            return null;
468        }
469
470        @Override
471        public Void visitClassType(ClassType t, Env<AttrContext> env) {
472            visit(t.getTypeArguments(), env);
473            if (!isAccessible(env, t, true)) {
474                accessBase(new AccessError(t.tsym), env.tree.pos(), env.enclClass.sym, t, t.tsym.name, true);
475            }
476            return null;
477        }
478
479        @Override
480        public Void visitWildcardType(WildcardType t, Env<AttrContext> env) {
481            visit(t.type, env);
482            return null;
483        }
484
485        @Override
486        public Void visitMethodType(MethodType t, Env<AttrContext> env) {
487            visit(t.getParameterTypes(), env);
488            visit(t.getReturnType(), env);
489            visit(t.getThrownTypes(), env);
490            return null;
491        }
492    };
493
494    /** Try to instantiate the type of a method so that it fits
495     *  given type arguments and argument types. If successful, return
496     *  the method's instantiated type, else return null.
497     *  The instantiation will take into account an additional leading
498     *  formal parameter if the method is an instance method seen as a member
499     *  of an under determined site. In this case, we treat site as an additional
500     *  parameter and the parameters of the class containing the method as
501     *  additional type variables that get instantiated.
502     *
503     *  @param env         The current environment
504     *  @param site        The type of which the method is a member.
505     *  @param m           The method symbol.
506     *  @param argtypes    The invocation's given value arguments.
507     *  @param typeargtypes    The invocation's given type arguments.
508     *  @param allowBoxing Allow boxing conversions of arguments.
509     *  @param useVarargs Box trailing arguments into an array for varargs.
510     */
511    Type rawInstantiate(Env<AttrContext> env,
512                        Type site,
513                        Symbol m,
514                        ResultInfo resultInfo,
515                        List<Type> argtypes,
516                        List<Type> typeargtypes,
517                        boolean allowBoxing,
518                        boolean useVarargs,
519                        Warner warn) throws Infer.InferenceException {
520
521        Type mt = types.memberType(site, m);
522        // tvars is the list of formal type variables for which type arguments
523        // need to inferred.
524        List<Type> tvars = List.nil();
525        if (typeargtypes == null) typeargtypes = List.nil();
526        if (!mt.hasTag(FORALL) && typeargtypes.nonEmpty()) {
527            // This is not a polymorphic method, but typeargs are supplied
528            // which is fine, see JLS 15.12.2.1
529        } else if (mt.hasTag(FORALL) && typeargtypes.nonEmpty()) {
530            ForAll pmt = (ForAll) mt;
531            if (typeargtypes.length() != pmt.tvars.length())
532                throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
533            // Check type arguments are within bounds
534            List<Type> formals = pmt.tvars;
535            List<Type> actuals = typeargtypes;
536            while (formals.nonEmpty() && actuals.nonEmpty()) {
537                List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head),
538                                                pmt.tvars, typeargtypes);
539                for (; bounds.nonEmpty(); bounds = bounds.tail)
540                    if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn))
541                        throw inapplicableMethodException.setMessage("explicit.param.do.not.conform.to.bounds",actuals.head, bounds);
542                formals = formals.tail;
543                actuals = actuals.tail;
544            }
545            mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes);
546        } else if (mt.hasTag(FORALL)) {
547            ForAll pmt = (ForAll) mt;
548            List<Type> tvars1 = types.newInstances(pmt.tvars);
549            tvars = tvars.appendList(tvars1);
550            mt = types.subst(pmt.qtype, pmt.tvars, tvars1);
551        }
552
553        // find out whether we need to go the slow route via infer
554        boolean instNeeded = tvars.tail != null; /*inlined: tvars.nonEmpty()*/
555        for (List<Type> l = argtypes;
556             l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
557             l = l.tail) {
558            if (l.head.hasTag(FORALL)) instNeeded = true;
559        }
560
561        if (instNeeded)
562            return infer.instantiateMethod(env,
563                                    tvars,
564                                    (MethodType)mt,
565                                    resultInfo,
566                                    (MethodSymbol)m,
567                                    argtypes,
568                                    allowBoxing,
569                                    useVarargs,
570                                    currentResolutionContext,
571                                    warn);
572
573        DeferredAttr.DeferredAttrContext dc = currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn);
574        currentResolutionContext.methodCheck.argumentsAcceptable(env, dc,
575                                argtypes, mt.getParameterTypes(), warn);
576        dc.complete();
577        return mt;
578    }
579
580    Type checkMethod(Env<AttrContext> env,
581                     Type site,
582                     Symbol m,
583                     ResultInfo resultInfo,
584                     List<Type> argtypes,
585                     List<Type> typeargtypes,
586                     Warner warn) {
587        MethodResolutionContext prevContext = currentResolutionContext;
588        try {
589            currentResolutionContext = new MethodResolutionContext();
590            currentResolutionContext.attrMode = DeferredAttr.AttrMode.CHECK;
591            if (env.tree.hasTag(JCTree.Tag.REFERENCE)) {
592                //method/constructor references need special check class
593                //to handle inference variables in 'argtypes' (might happen
594                //during an unsticking round)
595                currentResolutionContext.methodCheck =
596                        new MethodReferenceCheck(resultInfo.checkContext.inferenceContext());
597            }
598            MethodResolutionPhase step = currentResolutionContext.step = env.info.pendingResolutionPhase;
599            return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
600                    step.isBoxingRequired(), step.isVarargsRequired(), warn);
601        }
602        finally {
603            currentResolutionContext = prevContext;
604        }
605    }
606
607    /** Same but returns null instead throwing a NoInstanceException
608     */
609    Type instantiate(Env<AttrContext> env,
610                     Type site,
611                     Symbol m,
612                     ResultInfo resultInfo,
613                     List<Type> argtypes,
614                     List<Type> typeargtypes,
615                     boolean allowBoxing,
616                     boolean useVarargs,
617                     Warner warn) {
618        try {
619            return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
620                                  allowBoxing, useVarargs, warn);
621        } catch (InapplicableMethodException ex) {
622            return null;
623        }
624    }
625
626    /**
627     * This interface defines an entry point that should be used to perform a
628     * method check. A method check usually consist in determining as to whether
629     * a set of types (actuals) is compatible with another set of types (formals).
630     * Since the notion of compatibility can vary depending on the circumstances,
631     * this interfaces allows to easily add new pluggable method check routines.
632     */
633    interface MethodCheck {
634        /**
635         * Main method check routine. A method check usually consist in determining
636         * as to whether a set of types (actuals) is compatible with another set of
637         * types (formals). If an incompatibility is found, an unchecked exception
638         * is assumed to be thrown.
639         */
640        void argumentsAcceptable(Env<AttrContext> env,
641                                DeferredAttrContext deferredAttrContext,
642                                List<Type> argtypes,
643                                List<Type> formals,
644                                Warner warn);
645
646        /**
647         * Retrieve the method check object that will be used during a
648         * most specific check.
649         */
650        MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict);
651    }
652
653    /**
654     * Helper enum defining all method check diagnostics (used by resolveMethodCheck).
655     */
656    enum MethodCheckDiag {
657        /**
658         * Actuals and formals differs in length.
659         */
660        ARITY_MISMATCH("arg.length.mismatch", "infer.arg.length.mismatch"),
661        /**
662         * An actual is incompatible with a formal.
663         */
664        ARG_MISMATCH("no.conforming.assignment.exists", "infer.no.conforming.assignment.exists"),
665        /**
666         * An actual is incompatible with the varargs element type.
667         */
668        VARARG_MISMATCH("varargs.argument.mismatch", "infer.varargs.argument.mismatch"),
669        /**
670         * The varargs element type is inaccessible.
671         */
672        INACCESSIBLE_VARARGS("inaccessible.varargs.type", "inaccessible.varargs.type");
673
674        final String basicKey;
675        final String inferKey;
676
677        MethodCheckDiag(String basicKey, String inferKey) {
678            this.basicKey = basicKey;
679            this.inferKey = inferKey;
680        }
681
682        String regex() {
683            return String.format("([a-z]*\\.)*(%s|%s)", basicKey, inferKey);
684        }
685    }
686
687    /**
688     * Dummy method check object. All methods are deemed applicable, regardless
689     * of their formal parameter types.
690     */
691    MethodCheck nilMethodCheck = new MethodCheck() {
692        public void argumentsAcceptable(Env<AttrContext> env, DeferredAttrContext deferredAttrContext, List<Type> argtypes, List<Type> formals, Warner warn) {
693            //do nothing - method always applicable regardless of actuals
694        }
695
696        public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
697            return this;
698        }
699    };
700
701    /**
702     * Base class for 'real' method checks. The class defines the logic for
703     * iterating through formals and actuals and provides and entry point
704     * that can be used by subclasses in order to define the actual check logic.
705     */
706    abstract class AbstractMethodCheck implements MethodCheck {
707        @Override
708        public void argumentsAcceptable(final Env<AttrContext> env,
709                                    DeferredAttrContext deferredAttrContext,
710                                    List<Type> argtypes,
711                                    List<Type> formals,
712                                    Warner warn) {
713            //should we expand formals?
714            boolean useVarargs = deferredAttrContext.phase.isVarargsRequired();
715            List<JCExpression> trees = TreeInfo.args(env.tree);
716
717            //inference context used during this method check
718            InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
719
720            Type varargsFormal = useVarargs ? formals.last() : null;
721
722            if (varargsFormal == null &&
723                    argtypes.size() != formals.size()) {
724                reportMC(env.tree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
725            }
726
727            while (argtypes.nonEmpty() && formals.head != varargsFormal) {
728                DiagnosticPosition pos = trees != null ? trees.head : null;
729                checkArg(pos, false, argtypes.head, formals.head, deferredAttrContext, warn);
730                argtypes = argtypes.tail;
731                formals = formals.tail;
732                trees = trees != null ? trees.tail : trees;
733            }
734
735            if (formals.head != varargsFormal) {
736                reportMC(env.tree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
737            }
738
739            if (useVarargs) {
740                //note: if applicability check is triggered by most specific test,
741                //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
742                final Type elt = types.elemtype(varargsFormal);
743                while (argtypes.nonEmpty()) {
744                    DiagnosticPosition pos = trees != null ? trees.head : null;
745                    checkArg(pos, true, argtypes.head, elt, deferredAttrContext, warn);
746                    argtypes = argtypes.tail;
747                    trees = trees != null ? trees.tail : trees;
748                }
749            }
750        }
751
752        /**
753         * Does the actual argument conforms to the corresponding formal?
754         */
755        abstract void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn);
756
757        protected void reportMC(DiagnosticPosition pos, MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) {
758            boolean inferDiag = inferenceContext != infer.emptyContext;
759            InapplicableMethodException ex = inferDiag ?
760                    infer.inferenceException : inapplicableMethodException;
761            if (inferDiag && (!diag.inferKey.equals(diag.basicKey))) {
762                Object[] args2 = new Object[args.length + 1];
763                System.arraycopy(args, 0, args2, 1, args.length);
764                args2[0] = inferenceContext.inferenceVars();
765                args = args2;
766            }
767            String key = inferDiag ? diag.inferKey : diag.basicKey;
768            throw ex.setMessage(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args));
769        }
770
771        public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
772            return nilMethodCheck;
773        }
774
775    }
776
777    /**
778     * Arity-based method check. A method is applicable if the number of actuals
779     * supplied conforms to the method signature.
780     */
781    MethodCheck arityMethodCheck = new AbstractMethodCheck() {
782        @Override
783        void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
784            //do nothing - actual always compatible to formals
785        }
786
787        @Override
788        public String toString() {
789            return "arityMethodCheck";
790        }
791    };
792
793    List<Type> dummyArgs(int length) {
794        ListBuffer<Type> buf = new ListBuffer<>();
795        for (int i = 0 ; i < length ; i++) {
796            buf.append(Type.noType);
797        }
798        return buf.toList();
799    }
800
801    /**
802     * Main method applicability routine. Given a list of actual types A,
803     * a list of formal types F, determines whether the types in A are
804     * compatible (by method invocation conversion) with the types in F.
805     *
806     * Since this routine is shared between overload resolution and method
807     * type-inference, a (possibly empty) inference context is used to convert
808     * formal types to the corresponding 'undet' form ahead of a compatibility
809     * check so that constraints can be propagated and collected.
810     *
811     * Moreover, if one or more types in A is a deferred type, this routine uses
812     * DeferredAttr in order to perform deferred attribution. If one or more actual
813     * deferred types are stuck, they are placed in a queue and revisited later
814     * after the remainder of the arguments have been seen. If this is not sufficient
815     * to 'unstuck' the argument, a cyclic inference error is called out.
816     *
817     * A method check handler (see above) is used in order to report errors.
818     */
819    MethodCheck resolveMethodCheck = new AbstractMethodCheck() {
820
821        @Override
822        void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
823            ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn);
824            mresult.check(pos, actual);
825        }
826
827        @Override
828        public void argumentsAcceptable(final Env<AttrContext> env,
829                                    DeferredAttrContext deferredAttrContext,
830                                    List<Type> argtypes,
831                                    List<Type> formals,
832                                    Warner warn) {
833            super.argumentsAcceptable(env, deferredAttrContext, argtypes, formals, warn);
834            //should we expand formals?
835            if (deferredAttrContext.phase.isVarargsRequired()) {
836                Type typeToCheck = null;
837                if (!checkVarargsAccessAfterResolution) {
838                    typeToCheck = types.elemtype(formals.last());
839                } else if (deferredAttrContext.mode == AttrMode.CHECK) {
840                    typeToCheck = types.erasure(types.elemtype(formals.last()));
841                }
842                if (typeToCheck != null) {
843                    varargsAccessible(env, typeToCheck, deferredAttrContext.inferenceContext);
844                }
845            }
846        }
847
848        private void varargsAccessible(final Env<AttrContext> env, final Type t, final InferenceContext inferenceContext) {
849            if (inferenceContext.free(t)) {
850                inferenceContext.addFreeTypeListener(List.of(t), new FreeTypeListener() {
851                    @Override
852                    public void typesInferred(InferenceContext inferenceContext) {
853                        varargsAccessible(env, inferenceContext.asInstType(t), inferenceContext);
854                    }
855                });
856            } else {
857                if (!isAccessible(env, t)) {
858                    Symbol location = env.enclClass.sym;
859                    reportMC(env.tree, MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location);
860                }
861            }
862        }
863
864        private ResultInfo methodCheckResult(final boolean varargsCheck, Type to,
865                final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) {
866            CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) {
867                MethodCheckDiag methodDiag = varargsCheck ?
868                                 MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH;
869
870                @Override
871                public void report(DiagnosticPosition pos, JCDiagnostic details) {
872                    reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details);
873                }
874            };
875            return new MethodResultInfo(to, checkContext);
876        }
877
878        @Override
879        public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
880            return new MostSpecificCheck(strict, actuals);
881        }
882
883        @Override
884        public String toString() {
885            return "resolveMethodCheck";
886        }
887    };
888
889    /**
890     * This class handles method reference applicability checks; since during
891     * these checks it's sometime possible to have inference variables on
892     * the actual argument types list, the method applicability check must be
893     * extended so that inference variables are 'opened' as needed.
894     */
895    class MethodReferenceCheck extends AbstractMethodCheck {
896
897        InferenceContext pendingInferenceContext;
898
899        MethodReferenceCheck(InferenceContext pendingInferenceContext) {
900            this.pendingInferenceContext = pendingInferenceContext;
901        }
902
903        @Override
904        void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
905            ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn);
906            mresult.check(pos, actual);
907        }
908
909        private ResultInfo methodCheckResult(final boolean varargsCheck, Type to,
910                final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) {
911            CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) {
912                MethodCheckDiag methodDiag = varargsCheck ?
913                                 MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH;
914
915                @Override
916                public boolean compatible(Type found, Type req, Warner warn) {
917                    found = pendingInferenceContext.asUndetVar(found);
918                    if (found.hasTag(UNDETVAR) && req.isPrimitive()) {
919                        req = types.boxedClass(req).type;
920                    }
921                    return super.compatible(found, req, warn);
922                }
923
924                @Override
925                public void report(DiagnosticPosition pos, JCDiagnostic details) {
926                    reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details);
927                }
928            };
929            return new MethodResultInfo(to, checkContext);
930        }
931
932        @Override
933        public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
934            return new MostSpecificCheck(strict, actuals);
935        }
936
937        @Override
938        public String toString() {
939            return "MethodReferenceCheck";
940        }
941    }
942
943    /**
944     * Check context to be used during method applicability checks. A method check
945     * context might contain inference variables.
946     */
947    abstract class MethodCheckContext implements CheckContext {
948
949        boolean strict;
950        DeferredAttrContext deferredAttrContext;
951        Warner rsWarner;
952
953        public MethodCheckContext(boolean strict, DeferredAttrContext deferredAttrContext, Warner rsWarner) {
954           this.strict = strict;
955           this.deferredAttrContext = deferredAttrContext;
956           this.rsWarner = rsWarner;
957        }
958
959        public boolean compatible(Type found, Type req, Warner warn) {
960            InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
961            return strict ?
962                    types.isSubtypeUnchecked(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn) :
963                    types.isConvertible(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn);
964        }
965
966        public void report(DiagnosticPosition pos, JCDiagnostic details) {
967            throw inapplicableMethodException.setMessage(details);
968        }
969
970        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
971            return rsWarner;
972        }
973
974        public InferenceContext inferenceContext() {
975            return deferredAttrContext.inferenceContext;
976        }
977
978        public DeferredAttrContext deferredAttrContext() {
979            return deferredAttrContext;
980        }
981
982        @Override
983        public String toString() {
984            return "MethodCheckContext";
985        }
986    }
987
988    /**
989     * ResultInfo class to be used during method applicability checks. Check
990     * for deferred types goes through special path.
991     */
992    class MethodResultInfo extends ResultInfo {
993
994        public MethodResultInfo(Type pt, CheckContext checkContext) {
995            attr.super(VAL, pt, checkContext);
996        }
997
998        @Override
999        protected Type check(DiagnosticPosition pos, Type found) {
1000            if (found.hasTag(DEFERRED)) {
1001                DeferredType dt = (DeferredType)found;
1002                return dt.check(this);
1003            } else {
1004                Type uResult = U(found.baseType());
1005                Type capturedType = pos == null || pos.getTree() == null ?
1006                        types.capture(uResult) :
1007                        checkContext.inferenceContext()
1008                            .cachedCapture(pos.getTree(), uResult, true);
1009                return super.check(pos, chk.checkNonVoid(pos, capturedType));
1010            }
1011        }
1012
1013        /**
1014         * javac has a long-standing 'simplification' (see 6391995):
1015         * given an actual argument type, the method check is performed
1016         * on its upper bound. This leads to inconsistencies when an
1017         * argument type is checked against itself. For example, given
1018         * a type-variable T, it is not true that {@code U(T) <: T},
1019         * so we need to guard against that.
1020         */
1021        private Type U(Type found) {
1022            return found == pt ?
1023                    found : types.cvarUpperBound(found);
1024        }
1025
1026        @Override
1027        protected MethodResultInfo dup(Type newPt) {
1028            return new MethodResultInfo(newPt, checkContext);
1029        }
1030
1031        @Override
1032        protected ResultInfo dup(CheckContext newContext) {
1033            return new MethodResultInfo(pt, newContext);
1034        }
1035    }
1036
1037    /**
1038     * Most specific method applicability routine. Given a list of actual types A,
1039     * a list of formal types F1, and a list of formal types F2, the routine determines
1040     * as to whether the types in F1 can be considered more specific than those in F2 w.r.t.
1041     * argument types A.
1042     */
1043    class MostSpecificCheck implements MethodCheck {
1044
1045        boolean strict;
1046        List<Type> actuals;
1047
1048        MostSpecificCheck(boolean strict, List<Type> actuals) {
1049            this.strict = strict;
1050            this.actuals = actuals;
1051        }
1052
1053        @Override
1054        public void argumentsAcceptable(final Env<AttrContext> env,
1055                                    DeferredAttrContext deferredAttrContext,
1056                                    List<Type> formals1,
1057                                    List<Type> formals2,
1058                                    Warner warn) {
1059            formals2 = adjustArgs(formals2, deferredAttrContext.msym, formals1.length(), deferredAttrContext.phase.isVarargsRequired());
1060            while (formals2.nonEmpty()) {
1061                ResultInfo mresult = methodCheckResult(formals2.head, deferredAttrContext, warn, actuals.head);
1062                mresult.check(null, formals1.head);
1063                formals1 = formals1.tail;
1064                formals2 = formals2.tail;
1065                actuals = actuals.isEmpty() ? actuals : actuals.tail;
1066            }
1067        }
1068
1069       /**
1070        * Create a method check context to be used during the most specific applicability check
1071        */
1072        ResultInfo methodCheckResult(Type to, DeferredAttr.DeferredAttrContext deferredAttrContext,
1073               Warner rsWarner, Type actual) {
1074           return attr.new ResultInfo(Kinds.VAL, to,
1075                   new MostSpecificCheckContext(strict, deferredAttrContext, rsWarner, actual));
1076        }
1077
1078        /**
1079         * Subclass of method check context class that implements most specific
1080         * method conversion. If the actual type under analysis is a deferred type
1081         * a full blown structural analysis is carried out.
1082         */
1083        class MostSpecificCheckContext extends MethodCheckContext {
1084
1085            Type actual;
1086
1087            public MostSpecificCheckContext(boolean strict, DeferredAttrContext deferredAttrContext, Warner rsWarner, Type actual) {
1088                super(strict, deferredAttrContext, rsWarner);
1089                this.actual = actual;
1090            }
1091
1092            public boolean compatible(Type found, Type req, Warner warn) {
1093                if (allowFunctionalInterfaceMostSpecific &&
1094                        unrelatedFunctionalInterfaces(found, req) &&
1095                        (actual != null && actual.getTag() == DEFERRED)) {
1096                    DeferredType dt = (DeferredType) actual;
1097                    DeferredType.SpeculativeCache.Entry e =
1098                            dt.speculativeCache.get(deferredAttrContext.msym, deferredAttrContext.phase);
1099                    if (e != null && e.speculativeTree != deferredAttr.stuckTree) {
1100                        return functionalInterfaceMostSpecific(found, req, e.speculativeTree, warn);
1101                    }
1102                }
1103                return super.compatible(found, req, warn);
1104            }
1105
1106            /** Whether {@code t} and {@code s} are unrelated functional interface types. */
1107            private boolean unrelatedFunctionalInterfaces(Type t, Type s) {
1108                return types.isFunctionalInterface(t.tsym) &&
1109                       types.isFunctionalInterface(s.tsym) &&
1110                       types.asSuper(t, s.tsym) == null &&
1111                       types.asSuper(s, t.tsym) == null;
1112            }
1113
1114            /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
1115            private boolean functionalInterfaceMostSpecific(Type t, Type s, JCTree tree, Warner warn) {
1116                FunctionalInterfaceMostSpecificChecker msc = new FunctionalInterfaceMostSpecificChecker(t, s, warn);
1117                msc.scan(tree);
1118                return msc.result;
1119            }
1120
1121            /**
1122             * Tests whether one functional interface type can be considered more specific
1123             * than another unrelated functional interface type for the scanned expression.
1124             */
1125            class FunctionalInterfaceMostSpecificChecker extends DeferredAttr.PolyScanner {
1126
1127                final Type t;
1128                final Type s;
1129                final Warner warn;
1130                boolean result;
1131
1132                /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
1133                FunctionalInterfaceMostSpecificChecker(Type t, Type s, Warner warn) {
1134                    this.t = t;
1135                    this.s = s;
1136                    this.warn = warn;
1137                    result = true;
1138                }
1139
1140                @Override
1141                void skip(JCTree tree) {
1142                    result &= false;
1143                }
1144
1145                @Override
1146                public void visitConditional(JCConditional tree) {
1147                    scan(tree.truepart);
1148                    scan(tree.falsepart);
1149                }
1150
1151                @Override
1152                public void visitReference(JCMemberReference tree) {
1153                    Type desc_t = types.findDescriptorType(t);
1154                    Type desc_s = types.findDescriptorType(s);
1155                    // use inference variables here for more-specific inference (18.5.4)
1156                    if (!types.isSameTypes(desc_t.getParameterTypes(),
1157                            inferenceContext().asUndetVars(desc_s.getParameterTypes()))) {
1158                        result &= false;
1159                    } else {
1160                        // compare return types
1161                        Type ret_t = desc_t.getReturnType();
1162                        Type ret_s = desc_s.getReturnType();
1163                        if (ret_s.hasTag(VOID)) {
1164                            result &= true;
1165                        } else if (ret_t.hasTag(VOID)) {
1166                            result &= false;
1167                        } else if (ret_t.isPrimitive() != ret_s.isPrimitive()) {
1168                            boolean retValIsPrimitive =
1169                                    tree.refPolyKind == PolyKind.STANDALONE &&
1170                                    tree.sym.type.getReturnType().isPrimitive();
1171                            result &= (retValIsPrimitive == ret_t.isPrimitive()) &&
1172                                      (retValIsPrimitive != ret_s.isPrimitive());
1173                        } else {
1174                            result &= MostSpecificCheckContext.super.compatible(ret_t, ret_s, warn);
1175                        }
1176                    }
1177                }
1178
1179                @Override
1180                public void visitLambda(JCLambda tree) {
1181                    Type desc_t = types.findDescriptorType(t);
1182                    Type desc_s = types.findDescriptorType(s);
1183                    // use inference variables here for more-specific inference (18.5.4)
1184                    if (!types.isSameTypes(desc_t.getParameterTypes(),
1185                            inferenceContext().asUndetVars(desc_s.getParameterTypes()))) {
1186                        result &= false;
1187                    } else {
1188                        // compare return types
1189                        Type ret_t = desc_t.getReturnType();
1190                        Type ret_s = desc_s.getReturnType();
1191                        if (ret_s.hasTag(VOID)) {
1192                            result &= true;
1193                        } else if (ret_t.hasTag(VOID)) {
1194                            result &= false;
1195                        } else if (unrelatedFunctionalInterfaces(ret_t, ret_s)) {
1196                            for (JCExpression expr : lambdaResults(tree)) {
1197                                result &= functionalInterfaceMostSpecific(ret_t, ret_s, expr, warn);
1198                            }
1199                        } else if (ret_t.isPrimitive() != ret_s.isPrimitive()) {
1200                            for (JCExpression expr : lambdaResults(tree)) {
1201                                boolean retValIsPrimitive = expr.isStandalone() && expr.type.isPrimitive();
1202                                result &= (retValIsPrimitive == ret_t.isPrimitive()) &&
1203                                          (retValIsPrimitive != ret_s.isPrimitive());
1204                            }
1205                        } else {
1206                            result &= MostSpecificCheckContext.super.compatible(ret_t, ret_s, warn);
1207                        }
1208                    }
1209                }
1210                //where
1211
1212                private List<JCExpression> lambdaResults(JCLambda lambda) {
1213                    if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) {
1214                        return List.of((JCExpression) lambda.body);
1215                    } else {
1216                        final ListBuffer<JCExpression> buffer = new ListBuffer<>();
1217                        DeferredAttr.LambdaReturnScanner lambdaScanner =
1218                                new DeferredAttr.LambdaReturnScanner() {
1219                                    @Override
1220                                    public void visitReturn(JCReturn tree) {
1221                                        if (tree.expr != null) {
1222                                            buffer.append(tree.expr);
1223                                        }
1224                                    }
1225                                };
1226                        lambdaScanner.scan(lambda.body);
1227                        return buffer.toList();
1228                    }
1229                }
1230            }
1231
1232        }
1233
1234        public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
1235            Assert.error("Cannot get here!");
1236            return null;
1237        }
1238    }
1239
1240    public static class InapplicableMethodException extends RuntimeException {
1241        private static final long serialVersionUID = 0;
1242
1243        JCDiagnostic diagnostic;
1244        JCDiagnostic.Factory diags;
1245
1246        InapplicableMethodException(JCDiagnostic.Factory diags) {
1247            this.diagnostic = null;
1248            this.diags = diags;
1249        }
1250        InapplicableMethodException setMessage() {
1251            return setMessage((JCDiagnostic)null);
1252        }
1253        InapplicableMethodException setMessage(String key) {
1254            return setMessage(key != null ? diags.fragment(key) : null);
1255        }
1256        InapplicableMethodException setMessage(String key, Object... args) {
1257            return setMessage(key != null ? diags.fragment(key, args) : null);
1258        }
1259        InapplicableMethodException setMessage(JCDiagnostic diag) {
1260            this.diagnostic = diag;
1261            return this;
1262        }
1263
1264        public JCDiagnostic getDiagnostic() {
1265            return diagnostic;
1266        }
1267    }
1268    private final InapplicableMethodException inapplicableMethodException;
1269
1270/* ***************************************************************************
1271 *  Symbol lookup
1272 *  the following naming conventions for arguments are used
1273 *
1274 *       env      is the environment where the symbol was mentioned
1275 *       site     is the type of which the symbol is a member
1276 *       name     is the symbol's name
1277 *                if no arguments are given
1278 *       argtypes are the value arguments, if we search for a method
1279 *
1280 *  If no symbol was found, a ResolveError detailing the problem is returned.
1281 ****************************************************************************/
1282
1283    /** Find field. Synthetic fields are always skipped.
1284     *  @param env     The current environment.
1285     *  @param site    The original type from where the selection takes place.
1286     *  @param name    The name of the field.
1287     *  @param c       The class to search for the field. This is always
1288     *                 a superclass or implemented interface of site's class.
1289     */
1290    Symbol findField(Env<AttrContext> env,
1291                     Type site,
1292                     Name name,
1293                     TypeSymbol c) {
1294        while (c.type.hasTag(TYPEVAR))
1295            c = c.type.getUpperBound().tsym;
1296        Symbol bestSoFar = varNotFound;
1297        Symbol sym;
1298        for (Symbol s : c.members().getSymbolsByName(name)) {
1299            if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
1300                return isAccessible(env, site, s)
1301                    ? s : new AccessError(env, site, s);
1302            }
1303        }
1304        Type st = types.supertype(c.type);
1305        if (st != null && (st.hasTag(CLASS) || st.hasTag(TYPEVAR))) {
1306            sym = findField(env, site, name, st.tsym);
1307            if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1308        }
1309        for (List<Type> l = types.interfaces(c.type);
1310             bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
1311             l = l.tail) {
1312            sym = findField(env, site, name, l.head.tsym);
1313            if (bestSoFar.exists() && sym.exists() &&
1314                sym.owner != bestSoFar.owner)
1315                bestSoFar = new AmbiguityError(bestSoFar, sym);
1316            else if (sym.kind < bestSoFar.kind)
1317                bestSoFar = sym;
1318        }
1319        return bestSoFar;
1320    }
1321
1322    /** Resolve a field identifier, throw a fatal error if not found.
1323     *  @param pos       The position to use for error reporting.
1324     *  @param env       The environment current at the method invocation.
1325     *  @param site      The type of the qualifying expression, in which
1326     *                   identifier is searched.
1327     *  @param name      The identifier's name.
1328     */
1329    public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env,
1330                                          Type site, Name name) {
1331        Symbol sym = findField(env, site, name, site.tsym);
1332        if (sym.kind == VAR) return (VarSymbol)sym;
1333        else throw new FatalError(
1334                 diags.fragment("fatal.err.cant.locate.field",
1335                                name));
1336    }
1337
1338    /** Find unqualified variable or field with given name.
1339     *  Synthetic fields always skipped.
1340     *  @param env     The current environment.
1341     *  @param name    The name of the variable or field.
1342     */
1343    Symbol findVar(Env<AttrContext> env, Name name) {
1344        Symbol bestSoFar = varNotFound;
1345        Env<AttrContext> env1 = env;
1346        boolean staticOnly = false;
1347        while (env1.outer != null) {
1348            Symbol sym = null;
1349            if (isStatic(env1)) staticOnly = true;
1350            for (Symbol s : env1.info.scope.getSymbolsByName(name)) {
1351                if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
1352                    sym = s;
1353                    break;
1354                }
1355            }
1356            if (sym == null) {
1357                sym = findField(env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
1358            }
1359            if (sym.exists()) {
1360                if (staticOnly &&
1361                    sym.kind == VAR &&
1362                    sym.owner.kind == TYP &&
1363                    (sym.flags() & STATIC) == 0)
1364                    return new StaticError(sym);
1365                else
1366                    return sym;
1367            } else if (sym.kind < bestSoFar.kind) {
1368                bestSoFar = sym;
1369            }
1370
1371            if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
1372            env1 = env1.outer;
1373        }
1374
1375        Symbol sym = findField(env, syms.predefClass.type, name, syms.predefClass);
1376        if (sym.exists())
1377            return sym;
1378        if (bestSoFar.exists())
1379            return bestSoFar;
1380
1381        Symbol origin = null;
1382        for (Scope sc : new Scope[] { env.toplevel.namedImportScope, env.toplevel.starImportScope }) {
1383            for (Symbol currentSymbol : sc.getSymbolsByName(name)) {
1384                if (currentSymbol.kind != VAR)
1385                    continue;
1386                // invariant: sym.kind == VAR
1387                if (bestSoFar.kind < AMBIGUOUS && currentSymbol.owner != bestSoFar.owner)
1388                    return new AmbiguityError(bestSoFar, currentSymbol);
1389                else if (bestSoFar.kind >= VAR) {
1390                    origin = sc.getOrigin(currentSymbol).owner;
1391                    bestSoFar = isAccessible(env, origin.type, currentSymbol)
1392                        ? currentSymbol : new AccessError(env, origin.type, currentSymbol);
1393                }
1394            }
1395            if (bestSoFar.exists()) break;
1396        }
1397        if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type)
1398            return bestSoFar.clone(origin);
1399        else
1400            return bestSoFar;
1401    }
1402
1403    Warner noteWarner = new Warner();
1404
1405    /** Select the best method for a call site among two choices.
1406     *  @param env              The current environment.
1407     *  @param site             The original type from where the
1408     *                          selection takes place.
1409     *  @param argtypes         The invocation's value arguments,
1410     *  @param typeargtypes     The invocation's type arguments,
1411     *  @param sym              Proposed new best match.
1412     *  @param bestSoFar        Previously found best match.
1413     *  @param allowBoxing Allow boxing conversions of arguments.
1414     *  @param useVarargs Box trailing arguments into an array for varargs.
1415     */
1416    @SuppressWarnings("fallthrough")
1417    Symbol selectBest(Env<AttrContext> env,
1418                      Type site,
1419                      List<Type> argtypes,
1420                      List<Type> typeargtypes,
1421                      Symbol sym,
1422                      Symbol bestSoFar,
1423                      boolean allowBoxing,
1424                      boolean useVarargs,
1425                      boolean operator) {
1426        if (sym.kind == ERR ||
1427                !sym.isInheritedIn(site.tsym, types)) {
1428            return bestSoFar;
1429        } else if (useVarargs && (sym.flags() & VARARGS) == 0) {
1430            return bestSoFar.kind >= ERRONEOUS ?
1431                    new BadVarargsMethod((ResolveError)bestSoFar.baseSymbol()) :
1432                    bestSoFar;
1433        }
1434        Assert.check(sym.kind < AMBIGUOUS);
1435        try {
1436            Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes,
1437                               allowBoxing, useVarargs, types.noWarnings);
1438            if (!operator || verboseResolutionMode.contains(VerboseResolutionMode.PREDEF))
1439                currentResolutionContext.addApplicableCandidate(sym, mt);
1440        } catch (InapplicableMethodException ex) {
1441            if (!operator)
1442                currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic());
1443            switch (bestSoFar.kind) {
1444                case ABSENT_MTH:
1445                    return new InapplicableSymbolError(currentResolutionContext);
1446                case WRONG_MTH:
1447                    if (operator) return bestSoFar;
1448                    bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
1449                default:
1450                    return bestSoFar;
1451            }
1452        }
1453        if (!isAccessible(env, site, sym)) {
1454            return (bestSoFar.kind == ABSENT_MTH)
1455                ? new AccessError(env, site, sym)
1456                : bestSoFar;
1457        }
1458        return (bestSoFar.kind > AMBIGUOUS)
1459            ? sym
1460            : mostSpecific(argtypes, sym, bestSoFar, env, site,
1461                           allowBoxing && operator, useVarargs);
1462    }
1463
1464    /* Return the most specific of the two methods for a call,
1465     *  given that both are accessible and applicable.
1466     *  @param m1               A new candidate for most specific.
1467     *  @param m2               The previous most specific candidate.
1468     *  @param env              The current environment.
1469     *  @param site             The original type from where the selection
1470     *                          takes place.
1471     *  @param allowBoxing Allow boxing conversions of arguments.
1472     *  @param useVarargs Box trailing arguments into an array for varargs.
1473     */
1474    Symbol mostSpecific(List<Type> argtypes, Symbol m1,
1475                        Symbol m2,
1476                        Env<AttrContext> env,
1477                        final Type site,
1478                        boolean allowBoxing,
1479                        boolean useVarargs) {
1480        switch (m2.kind) {
1481        case MTH:
1482            if (m1 == m2) return m1;
1483            boolean m1SignatureMoreSpecific =
1484                    signatureMoreSpecific(argtypes, env, site, m1, m2, allowBoxing, useVarargs);
1485            boolean m2SignatureMoreSpecific =
1486                    signatureMoreSpecific(argtypes, env, site, m2, m1, allowBoxing, useVarargs);
1487            if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) {
1488                Type mt1 = types.memberType(site, m1);
1489                Type mt2 = types.memberType(site, m2);
1490                if (!types.overrideEquivalent(mt1, mt2))
1491                    return ambiguityError(m1, m2);
1492
1493                // same signature; select (a) the non-bridge method, or
1494                // (b) the one that overrides the other, or (c) the concrete
1495                // one, or (d) merge both abstract signatures
1496                if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE))
1497                    return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
1498
1499                // if one overrides or hides the other, use it
1500                TypeSymbol m1Owner = (TypeSymbol)m1.owner;
1501                TypeSymbol m2Owner = (TypeSymbol)m2.owner;
1502                if (types.asSuper(m1Owner.type, m2Owner) != null &&
1503                    ((m1.owner.flags_field & INTERFACE) == 0 ||
1504                     (m2.owner.flags_field & INTERFACE) != 0) &&
1505                    m1.overrides(m2, m1Owner, types, false))
1506                    return m1;
1507                if (types.asSuper(m2Owner.type, m1Owner) != null &&
1508                    ((m2.owner.flags_field & INTERFACE) == 0 ||
1509                     (m1.owner.flags_field & INTERFACE) != 0) &&
1510                    m2.overrides(m1, m2Owner, types, false))
1511                    return m2;
1512                boolean m1Abstract = (m1.flags() & ABSTRACT) != 0;
1513                boolean m2Abstract = (m2.flags() & ABSTRACT) != 0;
1514                if (m1Abstract && !m2Abstract) return m2;
1515                if (m2Abstract && !m1Abstract) return m1;
1516                // both abstract or both concrete
1517                return ambiguityError(m1, m2);
1518            }
1519            if (m1SignatureMoreSpecific) return m1;
1520            if (m2SignatureMoreSpecific) return m2;
1521            return ambiguityError(m1, m2);
1522        case AMBIGUOUS:
1523            //compare m1 to ambiguous methods in m2
1524            AmbiguityError e = (AmbiguityError)m2.baseSymbol();
1525            boolean m1MoreSpecificThanAnyAmbiguous = true;
1526            boolean allAmbiguousMoreSpecificThanM1 = true;
1527            for (Symbol s : e.ambiguousSyms) {
1528                Symbol moreSpecific = mostSpecific(argtypes, m1, s, env, site, allowBoxing, useVarargs);
1529                m1MoreSpecificThanAnyAmbiguous &= moreSpecific == m1;
1530                allAmbiguousMoreSpecificThanM1 &= moreSpecific == s;
1531            }
1532            if (m1MoreSpecificThanAnyAmbiguous)
1533                return m1;
1534            //if m1 is more specific than some ambiguous methods, but other ambiguous methods are
1535            //more specific than m1, add it as a new ambiguous method:
1536            if (!allAmbiguousMoreSpecificThanM1)
1537                e.addAmbiguousSymbol(m1);
1538            return e;
1539        default:
1540            throw new AssertionError();
1541        }
1542    }
1543    //where
1544    private boolean signatureMoreSpecific(List<Type> actuals, Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) {
1545        noteWarner.clear();
1546        int maxLength = Math.max(
1547                            Math.max(m1.type.getParameterTypes().length(), actuals.length()),
1548                            m2.type.getParameterTypes().length());
1549        MethodResolutionContext prevResolutionContext = currentResolutionContext;
1550        try {
1551            currentResolutionContext = new MethodResolutionContext();
1552            currentResolutionContext.step = prevResolutionContext.step;
1553            currentResolutionContext.methodCheck =
1554                    prevResolutionContext.methodCheck.mostSpecificCheck(actuals, !allowBoxing);
1555            Type mst = instantiate(env, site, m2, null,
1556                    adjustArgs(types.cvarLowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null,
1557                    allowBoxing, useVarargs, noteWarner);
1558            return mst != null &&
1559                    !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
1560        } finally {
1561            currentResolutionContext = prevResolutionContext;
1562        }
1563    }
1564
1565    List<Type> adjustArgs(List<Type> args, Symbol msym, int length, boolean allowVarargs) {
1566        if ((msym.flags() & VARARGS) != 0 && allowVarargs) {
1567            Type varargsElem = types.elemtype(args.last());
1568            if (varargsElem == null) {
1569                Assert.error("Bad varargs = " + args.last() + " " + msym);
1570            }
1571            List<Type> newArgs = args.reverse().tail.prepend(varargsElem).reverse();
1572            while (newArgs.length() < length) {
1573                newArgs = newArgs.append(newArgs.last());
1574            }
1575            return newArgs;
1576        } else {
1577            return args;
1578        }
1579    }
1580    //where
1581    Type mostSpecificReturnType(Type mt1, Type mt2) {
1582        Type rt1 = mt1.getReturnType();
1583        Type rt2 = mt2.getReturnType();
1584
1585        if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL)) {
1586            //if both are generic methods, adjust return type ahead of subtyping check
1587            rt1 = types.subst(rt1, mt1.getTypeArguments(), mt2.getTypeArguments());
1588        }
1589        //first use subtyping, then return type substitutability
1590        if (types.isSubtype(rt1, rt2)) {
1591            return mt1;
1592        } else if (types.isSubtype(rt2, rt1)) {
1593            return mt2;
1594        } else if (types.returnTypeSubstitutable(mt1, mt2)) {
1595            return mt1;
1596        } else if (types.returnTypeSubstitutable(mt2, mt1)) {
1597            return mt2;
1598        } else {
1599            return null;
1600        }
1601    }
1602    //where
1603    Symbol ambiguityError(Symbol m1, Symbol m2) {
1604        if (((m1.flags() | m2.flags()) & CLASH) != 0) {
1605            return (m1.flags() & CLASH) == 0 ? m1 : m2;
1606        } else {
1607            return new AmbiguityError(m1, m2);
1608        }
1609    }
1610
1611    Symbol findMethodInScope(Env<AttrContext> env,
1612            Type site,
1613            Name name,
1614            List<Type> argtypes,
1615            List<Type> typeargtypes,
1616            Scope sc,
1617            Symbol bestSoFar,
1618            boolean allowBoxing,
1619            boolean useVarargs,
1620            boolean operator,
1621            boolean abstractok) {
1622        for (Symbol s : sc.getSymbolsByName(name, new LookupFilter(abstractok))) {
1623            bestSoFar = selectBest(env, site, argtypes, typeargtypes, s,
1624                    bestSoFar, allowBoxing, useVarargs, operator);
1625        }
1626        return bestSoFar;
1627    }
1628    //where
1629        class LookupFilter implements Filter<Symbol> {
1630
1631            boolean abstractOk;
1632
1633            LookupFilter(boolean abstractOk) {
1634                this.abstractOk = abstractOk;
1635            }
1636
1637            public boolean accepts(Symbol s) {
1638                long flags = s.flags();
1639                return s.kind == MTH &&
1640                        (flags & SYNTHETIC) == 0 &&
1641                        (abstractOk ||
1642                        (flags & DEFAULT) != 0 ||
1643                        (flags & ABSTRACT) == 0);
1644            }
1645        }
1646
1647    /** Find best qualified method matching given name, type and value
1648     *  arguments.
1649     *  @param env       The current environment.
1650     *  @param site      The original type from where the selection
1651     *                   takes place.
1652     *  @param name      The method's name.
1653     *  @param argtypes  The method's value arguments.
1654     *  @param typeargtypes The method's type arguments
1655     *  @param allowBoxing Allow boxing conversions of arguments.
1656     *  @param useVarargs Box trailing arguments into an array for varargs.
1657     */
1658    Symbol findMethod(Env<AttrContext> env,
1659                      Type site,
1660                      Name name,
1661                      List<Type> argtypes,
1662                      List<Type> typeargtypes,
1663                      boolean allowBoxing,
1664                      boolean useVarargs,
1665                      boolean operator) {
1666        Symbol bestSoFar = methodNotFound;
1667        bestSoFar = findMethod(env,
1668                          site,
1669                          name,
1670                          argtypes,
1671                          typeargtypes,
1672                          site.tsym.type,
1673                          bestSoFar,
1674                          allowBoxing,
1675                          useVarargs,
1676                          operator);
1677        return bestSoFar;
1678    }
1679    // where
1680    private Symbol findMethod(Env<AttrContext> env,
1681                              Type site,
1682                              Name name,
1683                              List<Type> argtypes,
1684                              List<Type> typeargtypes,
1685                              Type intype,
1686                              Symbol bestSoFar,
1687                              boolean allowBoxing,
1688                              boolean useVarargs,
1689                              boolean operator) {
1690        @SuppressWarnings({"unchecked","rawtypes"})
1691        List<Type>[] itypes = (List<Type>[])new List[] { List.<Type>nil(), List.<Type>nil() };
1692        InterfaceLookupPhase iphase = InterfaceLookupPhase.ABSTRACT_OK;
1693        for (TypeSymbol s : superclasses(intype)) {
1694            bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1695                    s.members(), bestSoFar, allowBoxing, useVarargs, operator, true);
1696            if (name == names.init) return bestSoFar;
1697            iphase = (iphase == null) ? null : iphase.update(s, this);
1698            if (iphase != null) {
1699                for (Type itype : types.interfaces(s.type)) {
1700                    itypes[iphase.ordinal()] = types.union(types.closure(itype), itypes[iphase.ordinal()]);
1701                }
1702            }
1703        }
1704
1705        Symbol concrete = bestSoFar.kind < ERR &&
1706                (bestSoFar.flags() & ABSTRACT) == 0 ?
1707                bestSoFar : methodNotFound;
1708
1709        for (InterfaceLookupPhase iphase2 : InterfaceLookupPhase.values()) {
1710            //keep searching for abstract methods
1711            for (Type itype : itypes[iphase2.ordinal()]) {
1712                if (!itype.isInterface()) continue; //skip j.l.Object (included by Types.closure())
1713                if (iphase2 == InterfaceLookupPhase.DEFAULT_OK &&
1714                        (itype.tsym.flags() & DEFAULT) == 0) continue;
1715                bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1716                        itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, operator, true);
1717                if (concrete != bestSoFar &&
1718                        concrete.kind < ERR  && bestSoFar.kind < ERR &&
1719                        types.isSubSignature(concrete.type, bestSoFar.type)) {
1720                    //this is an hack - as javac does not do full membership checks
1721                    //most specific ends up comparing abstract methods that might have
1722                    //been implemented by some concrete method in a subclass and,
1723                    //because of raw override, it is possible for an abstract method
1724                    //to be more specific than the concrete method - so we need
1725                    //to explicitly call that out (see CR 6178365)
1726                    bestSoFar = concrete;
1727                }
1728            }
1729        }
1730        return bestSoFar;
1731    }
1732
1733    enum InterfaceLookupPhase {
1734        ABSTRACT_OK() {
1735            @Override
1736            InterfaceLookupPhase update(Symbol s, Resolve rs) {
1737                //We should not look for abstract methods if receiver is a concrete class
1738                //(as concrete classes are expected to implement all abstracts coming
1739                //from superinterfaces)
1740                if ((s.flags() & (ABSTRACT | INTERFACE | ENUM)) != 0) {
1741                    return this;
1742                } else {
1743                    return DEFAULT_OK;
1744                }
1745            }
1746        },
1747        DEFAULT_OK() {
1748            @Override
1749            InterfaceLookupPhase update(Symbol s, Resolve rs) {
1750                return this;
1751            }
1752        };
1753
1754        abstract InterfaceLookupPhase update(Symbol s, Resolve rs);
1755    }
1756
1757    /**
1758     * Return an Iterable object to scan the superclasses of a given type.
1759     * It's crucial that the scan is done lazily, as we don't want to accidentally
1760     * access more supertypes than strictly needed (as this could trigger completion
1761     * errors if some of the not-needed supertypes are missing/ill-formed).
1762     */
1763    Iterable<TypeSymbol> superclasses(final Type intype) {
1764        return new Iterable<TypeSymbol>() {
1765            public Iterator<TypeSymbol> iterator() {
1766                return new Iterator<TypeSymbol>() {
1767
1768                    List<TypeSymbol> seen = List.nil();
1769                    TypeSymbol currentSym = symbolFor(intype);
1770                    TypeSymbol prevSym = null;
1771
1772                    public boolean hasNext() {
1773                        if (currentSym == syms.noSymbol) {
1774                            currentSym = symbolFor(types.supertype(prevSym.type));
1775                        }
1776                        return currentSym != null;
1777                    }
1778
1779                    public TypeSymbol next() {
1780                        prevSym = currentSym;
1781                        currentSym = syms.noSymbol;
1782                        Assert.check(prevSym != null || prevSym != syms.noSymbol);
1783                        return prevSym;
1784                    }
1785
1786                    public void remove() {
1787                        throw new UnsupportedOperationException();
1788                    }
1789
1790                    TypeSymbol symbolFor(Type t) {
1791                        if (!t.hasTag(CLASS) &&
1792                                !t.hasTag(TYPEVAR)) {
1793                            return null;
1794                        }
1795                        while (t.hasTag(TYPEVAR))
1796                            t = t.getUpperBound();
1797                        if (seen.contains(t.tsym)) {
1798                            //degenerate case in which we have a circular
1799                            //class hierarchy - because of ill-formed classfiles
1800                            return null;
1801                        }
1802                        seen = seen.prepend(t.tsym);
1803                        return t.tsym;
1804                    }
1805                };
1806            }
1807        };
1808    }
1809
1810    /** Find unqualified method matching given name, type and value arguments.
1811     *  @param env       The current environment.
1812     *  @param name      The method's name.
1813     *  @param argtypes  The method's value arguments.
1814     *  @param typeargtypes  The method's type arguments.
1815     *  @param allowBoxing Allow boxing conversions of arguments.
1816     *  @param useVarargs Box trailing arguments into an array for varargs.
1817     */
1818    Symbol findFun(Env<AttrContext> env, Name name,
1819                   List<Type> argtypes, List<Type> typeargtypes,
1820                   boolean allowBoxing, boolean useVarargs) {
1821        Symbol bestSoFar = methodNotFound;
1822        Env<AttrContext> env1 = env;
1823        boolean staticOnly = false;
1824        while (env1.outer != null) {
1825            if (isStatic(env1)) staticOnly = true;
1826            Symbol sym = findMethod(
1827                env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
1828                allowBoxing, useVarargs, false);
1829            if (sym.exists()) {
1830                if (staticOnly &&
1831                    sym.kind == MTH &&
1832                    sym.owner.kind == TYP &&
1833                    (sym.flags() & STATIC) == 0) return new StaticError(sym);
1834                else return sym;
1835            } else if (sym.kind < bestSoFar.kind) {
1836                bestSoFar = sym;
1837            }
1838            if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
1839            env1 = env1.outer;
1840        }
1841
1842        Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
1843                                typeargtypes, allowBoxing, useVarargs, false);
1844        if (sym.exists())
1845            return sym;
1846
1847        for (Symbol currentSym : env.toplevel.namedImportScope.getSymbolsByName(name)) {
1848            Symbol origin = env.toplevel.namedImportScope.getOrigin(currentSym).owner;
1849            if (currentSym.kind == MTH) {
1850                if (currentSym.owner.type != origin.type)
1851                    currentSym = currentSym.clone(origin);
1852                if (!isAccessible(env, origin.type, currentSym))
1853                    currentSym = new AccessError(env, origin.type, currentSym);
1854                bestSoFar = selectBest(env, origin.type,
1855                                       argtypes, typeargtypes,
1856                                       currentSym, bestSoFar,
1857                                       allowBoxing, useVarargs, false);
1858            }
1859        }
1860        if (bestSoFar.exists())
1861            return bestSoFar;
1862
1863        for (Symbol currentSym : env.toplevel.starImportScope.getSymbolsByName(name)) {
1864            Symbol origin = env.toplevel.starImportScope.getOrigin(currentSym).owner;
1865            if (currentSym.kind == MTH) {
1866                if (currentSym.owner.type != origin.type)
1867                    currentSym = currentSym.clone(origin);
1868                if (!isAccessible(env, origin.type, currentSym))
1869                    currentSym = new AccessError(env, origin.type, currentSym);
1870                bestSoFar = selectBest(env, origin.type,
1871                                       argtypes, typeargtypes,
1872                                       currentSym, bestSoFar,
1873                                       allowBoxing, useVarargs, false);
1874            }
1875        }
1876        return bestSoFar;
1877    }
1878
1879    /** Load toplevel or member class with given fully qualified name and
1880     *  verify that it is accessible.
1881     *  @param env       The current environment.
1882     *  @param name      The fully qualified name of the class to be loaded.
1883     */
1884    Symbol loadClass(Env<AttrContext> env, Name name) {
1885        try {
1886            ClassSymbol c = finder.loadClass(name);
1887            return isAccessible(env, c) ? c : new AccessError(c);
1888        } catch (ClassFinder.BadClassFile err) {
1889            throw err;
1890        } catch (CompletionFailure ex) {
1891            return typeNotFound;
1892        }
1893    }
1894
1895
1896    /**
1897     * Find a type declared in a scope (not inherited).  Return null
1898     * if none is found.
1899     *  @param env       The current environment.
1900     *  @param site      The original type from where the selection takes
1901     *                   place.
1902     *  @param name      The type's name.
1903     *  @param c         The class to search for the member type. This is
1904     *                   always a superclass or implemented interface of
1905     *                   site's class.
1906     */
1907    Symbol findImmediateMemberType(Env<AttrContext> env,
1908                                   Type site,
1909                                   Name name,
1910                                   TypeSymbol c) {
1911        for (Symbol sym : c.members().getSymbolsByName(name)) {
1912            if (sym.kind == TYP) {
1913                return isAccessible(env, site, sym)
1914                    ? sym
1915                    : new AccessError(env, site, sym);
1916            }
1917        }
1918        return typeNotFound;
1919    }
1920
1921    /** Find a member type inherited from a superclass or interface.
1922     *  @param env       The current environment.
1923     *  @param site      The original type from where the selection takes
1924     *                   place.
1925     *  @param name      The type's name.
1926     *  @param c         The class to search for the member type. This is
1927     *                   always a superclass or implemented interface of
1928     *                   site's class.
1929     */
1930    Symbol findInheritedMemberType(Env<AttrContext> env,
1931                                   Type site,
1932                                   Name name,
1933                                   TypeSymbol c) {
1934        Symbol bestSoFar = typeNotFound;
1935        Symbol sym;
1936        Type st = types.supertype(c.type);
1937        if (st != null && st.hasTag(CLASS)) {
1938            sym = findMemberType(env, site, name, st.tsym);
1939            if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1940        }
1941        for (List<Type> l = types.interfaces(c.type);
1942             bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
1943             l = l.tail) {
1944            sym = findMemberType(env, site, name, l.head.tsym);
1945            if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&
1946                sym.owner != bestSoFar.owner)
1947                bestSoFar = new AmbiguityError(bestSoFar, sym);
1948            else if (sym.kind < bestSoFar.kind)
1949                bestSoFar = sym;
1950        }
1951        return bestSoFar;
1952    }
1953
1954    /** Find qualified member type.
1955     *  @param env       The current environment.
1956     *  @param site      The original type from where the selection takes
1957     *                   place.
1958     *  @param name      The type's name.
1959     *  @param c         The class to search for the member type. This is
1960     *                   always a superclass or implemented interface of
1961     *                   site's class.
1962     */
1963    Symbol findMemberType(Env<AttrContext> env,
1964                          Type site,
1965                          Name name,
1966                          TypeSymbol c) {
1967        Symbol sym = findImmediateMemberType(env, site, name, c);
1968
1969        if (sym != typeNotFound)
1970            return sym;
1971
1972        return findInheritedMemberType(env, site, name, c);
1973
1974    }
1975
1976    /** Find a global type in given scope and load corresponding class.
1977     *  @param env       The current environment.
1978     *  @param scope     The scope in which to look for the type.
1979     *  @param name      The type's name.
1980     */
1981    Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {
1982        Symbol bestSoFar = typeNotFound;
1983        for (Symbol s : scope.getSymbolsByName(name)) {
1984            Symbol sym = loadClass(env, s.flatName());
1985            if (bestSoFar.kind == TYP && sym.kind == TYP &&
1986                bestSoFar != sym)
1987                return new AmbiguityError(bestSoFar, sym);
1988            else if (sym.kind < bestSoFar.kind)
1989                bestSoFar = sym;
1990        }
1991        return bestSoFar;
1992    }
1993
1994    Symbol findTypeVar(Env<AttrContext> env, Name name, boolean staticOnly) {
1995        for (Symbol sym : env.info.scope.getSymbolsByName(name)) {
1996            if (sym.kind == TYP) {
1997                if (staticOnly &&
1998                    sym.type.hasTag(TYPEVAR) &&
1999                    sym.owner.kind == TYP)
2000                    return new StaticError(sym);
2001                return sym;
2002            }
2003        }
2004        return typeNotFound;
2005    }
2006
2007    /** Find an unqualified type symbol.
2008     *  @param env       The current environment.
2009     *  @param name      The type's name.
2010     */
2011    Symbol findType(Env<AttrContext> env, Name name) {
2012        Symbol bestSoFar = typeNotFound;
2013        Symbol sym;
2014        boolean staticOnly = false;
2015        for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {
2016            if (isStatic(env1)) staticOnly = true;
2017            // First, look for a type variable and the first member type
2018            final Symbol tyvar = findTypeVar(env1, name, staticOnly);
2019            sym = findImmediateMemberType(env1, env1.enclClass.sym.type,
2020                                          name, env1.enclClass.sym);
2021
2022            // Return the type variable if we have it, and have no
2023            // immediate member, OR the type variable is for a method.
2024            if (tyvar != typeNotFound) {
2025                if (sym == typeNotFound ||
2026                    (tyvar.kind == TYP && tyvar.exists() &&
2027                     tyvar.owner.kind == MTH))
2028                    return tyvar;
2029            }
2030
2031            // If the environment is a class def, finish up,
2032            // otherwise, do the entire findMemberType
2033            if (sym == typeNotFound)
2034                sym = findInheritedMemberType(env1, env1.enclClass.sym.type,
2035                                              name, env1.enclClass.sym);
2036
2037            if (staticOnly && sym.kind == TYP &&
2038                sym.type.hasTag(CLASS) &&
2039                sym.type.getEnclosingType().hasTag(CLASS) &&
2040                env1.enclClass.sym.type.isParameterized() &&
2041                sym.type.getEnclosingType().isParameterized())
2042                return new StaticError(sym);
2043            else if (sym.exists()) return sym;
2044            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
2045
2046            JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass;
2047            if ((encl.sym.flags() & STATIC) != 0)
2048                staticOnly = true;
2049        }
2050
2051        if (!env.tree.hasTag(IMPORT)) {
2052            sym = findGlobalType(env, env.toplevel.namedImportScope, name);
2053            if (sym.exists()) return sym;
2054            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
2055
2056            sym = findGlobalType(env, env.toplevel.packge.members(), name);
2057            if (sym.exists()) return sym;
2058            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
2059
2060            sym = findGlobalType(env, env.toplevel.starImportScope, name);
2061            if (sym.exists()) return sym;
2062            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
2063        }
2064
2065        return bestSoFar;
2066    }
2067
2068    /** Find an unqualified identifier which matches a specified kind set.
2069     *  @param env       The current environment.
2070     *  @param name      The identifier's name.
2071     *  @param kind      Indicates the possible symbol kinds
2072     *                   (a subset of VAL, TYP, PCK).
2073     */
2074    Symbol findIdent(Env<AttrContext> env, Name name, int kind) {
2075        Symbol bestSoFar = typeNotFound;
2076        Symbol sym;
2077
2078        if ((kind & VAR) != 0) {
2079            sym = findVar(env, name);
2080            if (sym.exists()) return sym;
2081            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
2082        }
2083
2084        if ((kind & TYP) != 0) {
2085            sym = findType(env, name);
2086            if (sym.kind==TYP) {
2087                 reportDependence(env.enclClass.sym, sym);
2088            }
2089            if (sym.exists()) return sym;
2090            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
2091        }
2092
2093        if ((kind & PCK) != 0) return syms.enterPackage(name);
2094        else return bestSoFar;
2095    }
2096
2097    /** Report dependencies.
2098     * @param from The enclosing class sym
2099     * @param to   The found identifier that the class depends on.
2100     */
2101    public void reportDependence(Symbol from, Symbol to) {
2102        // Override if you want to collect the reported dependencies.
2103    }
2104
2105    /** Find an identifier in a package which matches a specified kind set.
2106     *  @param env       The current environment.
2107     *  @param name      The identifier's name.
2108     *  @param kind      Indicates the possible symbol kinds
2109     *                   (a nonempty subset of TYP, PCK).
2110     */
2111    Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck,
2112                              Name name, int kind) {
2113        Name fullname = TypeSymbol.formFullName(name, pck);
2114        Symbol bestSoFar = typeNotFound;
2115        PackageSymbol pack = null;
2116        if ((kind & PCK) != 0) {
2117            pack = syms.enterPackage(fullname);
2118            if (pack.exists()) return pack;
2119        }
2120        if ((kind & TYP) != 0) {
2121            Symbol sym = loadClass(env, fullname);
2122            if (sym.exists()) {
2123                // don't allow programs to use flatnames
2124                if (name == sym.name) return sym;
2125            }
2126            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
2127        }
2128        return (pack != null) ? pack : bestSoFar;
2129    }
2130
2131    /** Find an identifier among the members of a given type `site'.
2132     *  @param env       The current environment.
2133     *  @param site      The type containing the symbol to be found.
2134     *  @param name      The identifier's name.
2135     *  @param kind      Indicates the possible symbol kinds
2136     *                   (a subset of VAL, TYP).
2137     */
2138    Symbol findIdentInType(Env<AttrContext> env, Type site,
2139                           Name name, int kind) {
2140        Symbol bestSoFar = typeNotFound;
2141        Symbol sym;
2142        if ((kind & VAR) != 0) {
2143            sym = findField(env, site, name, site.tsym);
2144            if (sym.exists()) return sym;
2145            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
2146        }
2147
2148        if ((kind & TYP) != 0) {
2149            sym = findMemberType(env, site, name, site.tsym);
2150            if (sym.exists()) return sym;
2151            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
2152        }
2153        return bestSoFar;
2154    }
2155
2156/* ***************************************************************************
2157 *  Access checking
2158 *  The following methods convert ResolveErrors to ErrorSymbols, issuing
2159 *  an error message in the process
2160 ****************************************************************************/
2161
2162    /** If `sym' is a bad symbol: report error and return errSymbol
2163     *  else pass through unchanged,
2164     *  additional arguments duplicate what has been used in trying to find the
2165     *  symbol {@literal (--> flyweight pattern)}. This improves performance since we
2166     *  expect misses to happen frequently.
2167     *
2168     *  @param sym       The symbol that was found, or a ResolveError.
2169     *  @param pos       The position to use for error reporting.
2170     *  @param location  The symbol the served as a context for this lookup
2171     *  @param site      The original type from where the selection took place.
2172     *  @param name      The symbol's name.
2173     *  @param qualified Did we get here through a qualified expression resolution?
2174     *  @param argtypes  The invocation's value arguments,
2175     *                   if we looked for a method.
2176     *  @param typeargtypes  The invocation's type arguments,
2177     *                   if we looked for a method.
2178     *  @param logResolveHelper helper class used to log resolve errors
2179     */
2180    Symbol accessInternal(Symbol sym,
2181                  DiagnosticPosition pos,
2182                  Symbol location,
2183                  Type site,
2184                  Name name,
2185                  boolean qualified,
2186                  List<Type> argtypes,
2187                  List<Type> typeargtypes,
2188                  LogResolveHelper logResolveHelper) {
2189        if (sym.kind >= AMBIGUOUS) {
2190            ResolveError errSym = (ResolveError)sym.baseSymbol();
2191            sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol);
2192            argtypes = logResolveHelper.getArgumentTypes(errSym, sym, name, argtypes);
2193            if (logResolveHelper.resolveDiagnosticNeeded(site, argtypes, typeargtypes)) {
2194                logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes);
2195            }
2196        }
2197        return sym;
2198    }
2199
2200    /**
2201     * Variant of the generalized access routine, to be used for generating method
2202     * resolution diagnostics
2203     */
2204    Symbol accessMethod(Symbol sym,
2205                  DiagnosticPosition pos,
2206                  Symbol location,
2207                  Type site,
2208                  Name name,
2209                  boolean qualified,
2210                  List<Type> argtypes,
2211                  List<Type> typeargtypes) {
2212        return accessInternal(sym, pos, location, site, name, qualified, argtypes, typeargtypes, methodLogResolveHelper);
2213    }
2214
2215    /** Same as original accessMethod(), but without location.
2216     */
2217    Symbol accessMethod(Symbol sym,
2218                  DiagnosticPosition pos,
2219                  Type site,
2220                  Name name,
2221                  boolean qualified,
2222                  List<Type> argtypes,
2223                  List<Type> typeargtypes) {
2224        return accessMethod(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes);
2225    }
2226
2227    /**
2228     * Variant of the generalized access routine, to be used for generating variable,
2229     * type resolution diagnostics
2230     */
2231    Symbol accessBase(Symbol sym,
2232                  DiagnosticPosition pos,
2233                  Symbol location,
2234                  Type site,
2235                  Name name,
2236                  boolean qualified) {
2237        return accessInternal(sym, pos, location, site, name, qualified, List.<Type>nil(), null, basicLogResolveHelper);
2238    }
2239
2240    /** Same as original accessBase(), but without location.
2241     */
2242    Symbol accessBase(Symbol sym,
2243                  DiagnosticPosition pos,
2244                  Type site,
2245                  Name name,
2246                  boolean qualified) {
2247        return accessBase(sym, pos, site.tsym, site, name, qualified);
2248    }
2249
2250    interface LogResolveHelper {
2251        boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes);
2252        List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes);
2253    }
2254
2255    LogResolveHelper basicLogResolveHelper = new LogResolveHelper() {
2256        public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2257            return !site.isErroneous();
2258        }
2259        public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2260            return argtypes;
2261        }
2262    };
2263
2264    LogResolveHelper methodLogResolveHelper = new LogResolveHelper() {
2265        public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2266            return !site.isErroneous() &&
2267                        !Type.isErroneous(argtypes) &&
2268                        (typeargtypes == null || !Type.isErroneous(typeargtypes));
2269        }
2270        public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2271            return (syms.operatorNames.contains(name)) ?
2272                    argtypes :
2273                    Type.map(argtypes, new ResolveDeferredRecoveryMap(AttrMode.SPECULATIVE, accessedSym, currentResolutionContext.step));
2274        }
2275    };
2276
2277    class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap {
2278
2279        public ResolveDeferredRecoveryMap(AttrMode mode, Symbol msym, MethodResolutionPhase step) {
2280            deferredAttr.super(mode, msym, step);
2281        }
2282
2283        @Override
2284        protected Type typeOf(DeferredType dt) {
2285            Type res = super.typeOf(dt);
2286            if (!res.isErroneous()) {
2287                switch (TreeInfo.skipParens(dt.tree).getTag()) {
2288                    case LAMBDA:
2289                    case REFERENCE:
2290                        return dt;
2291                    case CONDEXPR:
2292                        return res == Type.recoveryType ?
2293                                dt : res;
2294                }
2295            }
2296            return res;
2297        }
2298    }
2299
2300    /** Check that sym is not an abstract method.
2301     */
2302    void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
2303        if ((sym.flags() & ABSTRACT) != 0 && (sym.flags() & DEFAULT) == 0)
2304            log.error(pos, "abstract.cant.be.accessed.directly",
2305                      kindName(sym), sym, sym.location());
2306    }
2307
2308/* ***************************************************************************
2309 *  Name resolution
2310 *  Naming conventions are as for symbol lookup
2311 *  Unlike the find... methods these methods will report access errors
2312 ****************************************************************************/
2313
2314    /** Resolve an unqualified (non-method) identifier.
2315     *  @param pos       The position to use for error reporting.
2316     *  @param env       The environment current at the identifier use.
2317     *  @param name      The identifier's name.
2318     *  @param kind      The set of admissible symbol kinds for the identifier.
2319     */
2320    Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,
2321                        Name name, int kind) {
2322        return accessBase(
2323            findIdent(env, name, kind),
2324            pos, env.enclClass.sym.type, name, false);
2325    }
2326
2327    /** Resolve an unqualified method identifier.
2328     *  @param pos       The position to use for error reporting.
2329     *  @param env       The environment current at the method invocation.
2330     *  @param name      The identifier's name.
2331     *  @param argtypes  The types of the invocation's value arguments.
2332     *  @param typeargtypes  The types of the invocation's type arguments.
2333     */
2334    Symbol resolveMethod(DiagnosticPosition pos,
2335                         Env<AttrContext> env,
2336                         Name name,
2337                         List<Type> argtypes,
2338                         List<Type> typeargtypes) {
2339        return lookupMethod(env, pos, env.enclClass.sym, resolveMethodCheck,
2340                new BasicLookupHelper(name, env.enclClass.sym.type, argtypes, typeargtypes) {
2341                    @Override
2342                    Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2343                        return findFun(env, name, argtypes, typeargtypes,
2344                                phase.isBoxingRequired(),
2345                                phase.isVarargsRequired());
2346                    }});
2347    }
2348
2349    /** Resolve a qualified method identifier
2350     *  @param pos       The position to use for error reporting.
2351     *  @param env       The environment current at the method invocation.
2352     *  @param site      The type of the qualifying expression, in which
2353     *                   identifier is searched.
2354     *  @param name      The identifier's name.
2355     *  @param argtypes  The types of the invocation's value arguments.
2356     *  @param typeargtypes  The types of the invocation's type arguments.
2357     */
2358    Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
2359                                  Type site, Name name, List<Type> argtypes,
2360                                  List<Type> typeargtypes) {
2361        return resolveQualifiedMethod(pos, env, site.tsym, site, name, argtypes, typeargtypes);
2362    }
2363    Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
2364                                  Symbol location, Type site, Name name, List<Type> argtypes,
2365                                  List<Type> typeargtypes) {
2366        return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes);
2367    }
2368    private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext,
2369                                  DiagnosticPosition pos, Env<AttrContext> env,
2370                                  Symbol location, Type site, Name name, List<Type> argtypes,
2371                                  List<Type> typeargtypes) {
2372        return lookupMethod(env, pos, location, resolveContext, new BasicLookupHelper(name, site, argtypes, typeargtypes) {
2373            @Override
2374            Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2375                return findMethod(env, site, name, argtypes, typeargtypes,
2376                        phase.isBoxingRequired(),
2377                        phase.isVarargsRequired(), false);
2378            }
2379            @Override
2380            Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2381                if (sym.kind >= AMBIGUOUS) {
2382                    sym = super.access(env, pos, location, sym);
2383                } else if (allowMethodHandles) {
2384                    MethodSymbol msym = (MethodSymbol)sym;
2385                    if ((msym.flags() & SIGNATURE_POLYMORPHIC) != 0) {
2386                        return findPolymorphicSignatureInstance(env, sym, argtypes);
2387                    }
2388                }
2389                return sym;
2390            }
2391        });
2392    }
2393
2394    /** Find or create an implicit method of exactly the given type (after erasure).
2395     *  Searches in a side table, not the main scope of the site.
2396     *  This emulates the lookup process required by JSR 292 in JVM.
2397     *  @param env       Attribution environment
2398     *  @param spMethod  signature polymorphic method - i.e. MH.invokeExact
2399     *  @param argtypes  The required argument types
2400     */
2401    Symbol findPolymorphicSignatureInstance(Env<AttrContext> env,
2402                                            final Symbol spMethod,
2403                                            List<Type> argtypes) {
2404        Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
2405                (MethodSymbol)spMethod, currentResolutionContext, argtypes);
2406        for (Symbol sym : polymorphicSignatureScope.getSymbolsByName(spMethod.name)) {
2407            if (types.isSameType(mtype, sym.type)) {
2408               return sym;
2409            }
2410        }
2411
2412        // create the desired method
2413        long flags = ABSTRACT | HYPOTHETICAL | spMethod.flags() & Flags.AccessFlags;
2414        Symbol msym = new MethodSymbol(flags, spMethod.name, mtype, spMethod.owner) {
2415            @Override
2416            public Symbol baseSymbol() {
2417                return spMethod;
2418            }
2419        };
2420        polymorphicSignatureScope.enter(msym);
2421        return msym;
2422    }
2423
2424    /** Resolve a qualified method identifier, throw a fatal error if not
2425     *  found.
2426     *  @param pos       The position to use for error reporting.
2427     *  @param env       The environment current at the method invocation.
2428     *  @param site      The type of the qualifying expression, in which
2429     *                   identifier is searched.
2430     *  @param name      The identifier's name.
2431     *  @param argtypes  The types of the invocation's value arguments.
2432     *  @param typeargtypes  The types of the invocation's type arguments.
2433     */
2434    public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env,
2435                                        Type site, Name name,
2436                                        List<Type> argtypes,
2437                                        List<Type> typeargtypes) {
2438        MethodResolutionContext resolveContext = new MethodResolutionContext();
2439        resolveContext.internalResolution = true;
2440        Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym,
2441                site, name, argtypes, typeargtypes);
2442        if (sym.kind == MTH) return (MethodSymbol)sym;
2443        else throw new FatalError(
2444                 diags.fragment("fatal.err.cant.locate.meth",
2445                                name));
2446    }
2447
2448    /** Resolve constructor.
2449     *  @param pos       The position to use for error reporting.
2450     *  @param env       The environment current at the constructor invocation.
2451     *  @param site      The type of class for which a constructor is searched.
2452     *  @param argtypes  The types of the constructor invocation's value
2453     *                   arguments.
2454     *  @param typeargtypes  The types of the constructor invocation's type
2455     *                   arguments.
2456     */
2457    Symbol resolveConstructor(DiagnosticPosition pos,
2458                              Env<AttrContext> env,
2459                              Type site,
2460                              List<Type> argtypes,
2461                              List<Type> typeargtypes) {
2462        return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes);
2463    }
2464
2465    private Symbol resolveConstructor(MethodResolutionContext resolveContext,
2466                              final DiagnosticPosition pos,
2467                              Env<AttrContext> env,
2468                              Type site,
2469                              List<Type> argtypes,
2470                              List<Type> typeargtypes) {
2471        return lookupMethod(env, pos, site.tsym, resolveContext, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2472            @Override
2473            Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2474                return findConstructor(pos, env, site, argtypes, typeargtypes,
2475                        phase.isBoxingRequired(),
2476                        phase.isVarargsRequired());
2477            }
2478        });
2479    }
2480
2481    /** Resolve a constructor, throw a fatal error if not found.
2482     *  @param pos       The position to use for error reporting.
2483     *  @param env       The environment current at the method invocation.
2484     *  @param site      The type to be constructed.
2485     *  @param argtypes  The types of the invocation's value arguments.
2486     *  @param typeargtypes  The types of the invocation's type arguments.
2487     */
2488    public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2489                                        Type site,
2490                                        List<Type> argtypes,
2491                                        List<Type> typeargtypes) {
2492        MethodResolutionContext resolveContext = new MethodResolutionContext();
2493        resolveContext.internalResolution = true;
2494        Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
2495        if (sym.kind == MTH) return (MethodSymbol)sym;
2496        else throw new FatalError(
2497                 diags.fragment("fatal.err.cant.locate.ctor", site));
2498    }
2499
2500    Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2501                              Type site, List<Type> argtypes,
2502                              List<Type> typeargtypes,
2503                              boolean allowBoxing,
2504                              boolean useVarargs) {
2505        Symbol sym = findMethod(env, site,
2506                                    names.init, argtypes,
2507                                    typeargtypes, allowBoxing,
2508                                    useVarargs, false);
2509        chk.checkDeprecated(pos, env.info.scope.owner, sym);
2510        return sym;
2511    }
2512
2513    /** Resolve constructor using diamond inference.
2514     *  @param pos       The position to use for error reporting.
2515     *  @param env       The environment current at the constructor invocation.
2516     *  @param site      The type of class for which a constructor is searched.
2517     *                   The scope of this class has been touched in attribution.
2518     *  @param argtypes  The types of the constructor invocation's value
2519     *                   arguments.
2520     *  @param typeargtypes  The types of the constructor invocation's type
2521     *                   arguments.
2522     */
2523    Symbol resolveDiamond(DiagnosticPosition pos,
2524                              Env<AttrContext> env,
2525                              Type site,
2526                              List<Type> argtypes,
2527                              List<Type> typeargtypes) {
2528        return lookupMethod(env, pos, site.tsym, resolveMethodCheck,
2529                new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2530                    @Override
2531                    Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2532                        return findDiamond(env, site, argtypes, typeargtypes,
2533                                phase.isBoxingRequired(),
2534                                phase.isVarargsRequired());
2535                    }
2536                    @Override
2537                    Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2538                        if (sym.kind >= AMBIGUOUS) {
2539                            if (sym.kind != WRONG_MTH && sym.kind != WRONG_MTHS) {
2540                                sym = super.access(env, pos, location, sym);
2541                            } else {
2542                                final JCDiagnostic details = sym.kind == WRONG_MTH ?
2543                                                ((InapplicableSymbolError)sym.baseSymbol()).errCandidate().snd :
2544                                                null;
2545                                sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) {
2546                                    @Override
2547                                    JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
2548                                            Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
2549                                        String key = details == null ?
2550                                            "cant.apply.diamond" :
2551                                            "cant.apply.diamond.1";
2552                                        return diags.create(dkind, log.currentSource(), pos, key,
2553                                                diags.fragment("diamond", site.tsym), details);
2554                                    }
2555                                };
2556                                sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
2557                                env.info.pendingResolutionPhase = currentResolutionContext.step;
2558                            }
2559                        }
2560                        return sym;
2561                    }});
2562    }
2563
2564    /** This method scans all the constructor symbol in a given class scope -
2565     *  assuming that the original scope contains a constructor of the kind:
2566     *  {@code Foo(X x, Y y)}, where X,Y are class type-variables declared in Foo,
2567     *  a method check is executed against the modified constructor type:
2568     *  {@code <X,Y>Foo<X,Y>(X x, Y y)}. This is crucial in order to enable diamond
2569     *  inference. The inferred return type of the synthetic constructor IS
2570     *  the inferred type for the diamond operator.
2571     */
2572    private Symbol findDiamond(Env<AttrContext> env,
2573                              Type site,
2574                              List<Type> argtypes,
2575                              List<Type> typeargtypes,
2576                              boolean allowBoxing,
2577                              boolean useVarargs) {
2578        Symbol bestSoFar = methodNotFound;
2579        for (final Symbol sym : site.tsym.members().getSymbolsByName(names.init)) {
2580            //- System.out.println(" e " + e.sym);
2581            if (sym.kind == MTH &&
2582                (sym.flags_field & SYNTHETIC) == 0) {
2583                    List<Type> oldParams = sym.type.hasTag(FORALL) ?
2584                            ((ForAll)sym.type).tvars :
2585                            List.<Type>nil();
2586                    Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
2587                                                 types.createMethodTypeWithReturn(sym.type.asMethodType(), site));
2588                    MethodSymbol newConstr = new MethodSymbol(sym.flags(), names.init, constrType, site.tsym) {
2589                        @Override
2590                        public Symbol baseSymbol() {
2591                            return sym;
2592                        }
2593                    };
2594                    bestSoFar = selectBest(env, site, argtypes, typeargtypes,
2595                            newConstr,
2596                            bestSoFar,
2597                            allowBoxing,
2598                            useVarargs,
2599                            false);
2600            }
2601        }
2602        return bestSoFar;
2603    }
2604
2605
2606
2607    /** Resolve operator.
2608     *  @param pos       The position to use for error reporting.
2609     *  @param optag     The tag of the operation tree.
2610     *  @param env       The environment current at the operation.
2611     *  @param argtypes  The types of the operands.
2612     */
2613    Symbol resolveOperator(DiagnosticPosition pos, JCTree.Tag optag,
2614                           Env<AttrContext> env, List<Type> argtypes) {
2615        MethodResolutionContext prevResolutionContext = currentResolutionContext;
2616        try {
2617            currentResolutionContext = new MethodResolutionContext();
2618            Name name = treeinfo.operatorName(optag);
2619            return lookupMethod(env, pos, syms.predefClass, currentResolutionContext,
2620                    new BasicLookupHelper(name, syms.predefClass.type, argtypes, null, BOX) {
2621                @Override
2622                Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2623                    return findMethod(env, site, name, argtypes, typeargtypes,
2624                            phase.isBoxingRequired(),
2625                            phase.isVarargsRequired(), true);
2626                }
2627                @Override
2628                Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2629                    return accessMethod(sym, pos, env.enclClass.sym.type, name,
2630                          false, argtypes, null);
2631                }
2632            });
2633        } finally {
2634            currentResolutionContext = prevResolutionContext;
2635        }
2636    }
2637
2638    /** Resolve operator.
2639     *  @param pos       The position to use for error reporting.
2640     *  @param optag     The tag of the operation tree.
2641     *  @param env       The environment current at the operation.
2642     *  @param arg       The type of the operand.
2643     */
2644    Symbol resolveUnaryOperator(DiagnosticPosition pos, JCTree.Tag optag, Env<AttrContext> env, Type arg) {
2645        return resolveOperator(pos, optag, env, List.of(arg));
2646    }
2647
2648    /** Resolve binary operator.
2649     *  @param pos       The position to use for error reporting.
2650     *  @param optag     The tag of the operation tree.
2651     *  @param env       The environment current at the operation.
2652     *  @param left      The types of the left operand.
2653     *  @param right     The types of the right operand.
2654     */
2655    Symbol resolveBinaryOperator(DiagnosticPosition pos,
2656                                 JCTree.Tag optag,
2657                                 Env<AttrContext> env,
2658                                 Type left,
2659                                 Type right) {
2660        return resolveOperator(pos, optag, env, List.of(left, right));
2661    }
2662
2663    Symbol getMemberReference(DiagnosticPosition pos,
2664            Env<AttrContext> env,
2665            JCMemberReference referenceTree,
2666            Type site,
2667            Name name) {
2668
2669        site = types.capture(site);
2670
2671        ReferenceLookupHelper lookupHelper = makeReferenceLookupHelper(
2672                referenceTree, site, name, List.<Type>nil(), null, VARARITY);
2673
2674        Env<AttrContext> newEnv = env.dup(env.tree, env.info.dup());
2675        Symbol sym = lookupMethod(newEnv, env.tree.pos(), site.tsym,
2676                nilMethodCheck, lookupHelper);
2677
2678        env.info.pendingResolutionPhase = newEnv.info.pendingResolutionPhase;
2679
2680        return sym;
2681    }
2682
2683    ReferenceLookupHelper makeReferenceLookupHelper(JCMemberReference referenceTree,
2684                                  Type site,
2685                                  Name name,
2686                                  List<Type> argtypes,
2687                                  List<Type> typeargtypes,
2688                                  MethodResolutionPhase maxPhase) {
2689        ReferenceLookupHelper result;
2690        if (!name.equals(names.init)) {
2691            //method reference
2692            result =
2693                    new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
2694        } else {
2695            if (site.hasTag(ARRAY)) {
2696                //array constructor reference
2697                result =
2698                        new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
2699            } else {
2700                //class constructor reference
2701                result =
2702                        new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
2703            }
2704        }
2705        return result;
2706    }
2707
2708    Symbol resolveMemberReferenceByArity(Env<AttrContext> env,
2709                                  JCMemberReference referenceTree,
2710                                  Type site,
2711                                  Name name,
2712                                  List<Type> argtypes,
2713                                  InferenceContext inferenceContext) {
2714
2715        boolean isStaticSelector = TreeInfo.isStaticSelector(referenceTree.expr, names);
2716        site = types.capture(site);
2717
2718        ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper(
2719                referenceTree, site, name, argtypes, null, VARARITY);
2720        //step 1 - bound lookup
2721        Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
2722        Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym,
2723                arityMethodCheck, boundLookupHelper);
2724        if (isStaticSelector &&
2725            !name.equals(names.init) &&
2726            !boundSym.isStatic() &&
2727            boundSym.kind < ERRONEOUS) {
2728            boundSym = methodNotFound;
2729        }
2730
2731        //step 2 - unbound lookup
2732        Symbol unboundSym = methodNotFound;
2733        ReferenceLookupHelper unboundLookupHelper = null;
2734        Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
2735        if (isStaticSelector) {
2736            unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext);
2737            unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym,
2738                    arityMethodCheck, unboundLookupHelper);
2739            if (unboundSym.isStatic() &&
2740                unboundSym.kind < ERRONEOUS) {
2741                unboundSym = methodNotFound;
2742            }
2743        }
2744
2745        //merge results
2746        Symbol bestSym = choose(boundSym, unboundSym);
2747        env.info.pendingResolutionPhase = bestSym == unboundSym ?
2748                unboundEnv.info.pendingResolutionPhase :
2749                boundEnv.info.pendingResolutionPhase;
2750
2751        return bestSym;
2752    }
2753
2754    /**
2755     * Resolution of member references is typically done as a single
2756     * overload resolution step, where the argument types A are inferred from
2757     * the target functional descriptor.
2758     *
2759     * If the member reference is a method reference with a type qualifier,
2760     * a two-step lookup process is performed. The first step uses the
2761     * expected argument list A, while the second step discards the first
2762     * type from A (which is treated as a receiver type).
2763     *
2764     * There are two cases in which inference is performed: (i) if the member
2765     * reference is a constructor reference and the qualifier type is raw - in
2766     * which case diamond inference is used to infer a parameterization for the
2767     * type qualifier; (ii) if the member reference is an unbound reference
2768     * where the type qualifier is raw - in that case, during the unbound lookup
2769     * the receiver argument type is used to infer an instantiation for the raw
2770     * qualifier type.
2771     *
2772     * When a multi-step resolution process is exploited, it is an error
2773     * if two candidates are found (ambiguity).
2774     *
2775     * This routine returns a pair (T,S), where S is the member reference symbol,
2776     * and T is the type of the class in which S is defined. This is necessary as
2777     * the type T might be dynamically inferred (i.e. if constructor reference
2778     * has a raw qualifier).
2779     */
2780    Pair<Symbol, ReferenceLookupHelper> resolveMemberReference(Env<AttrContext> env,
2781                                  JCMemberReference referenceTree,
2782                                  Type site,
2783                                  Name name,
2784                                  List<Type> argtypes,
2785                                  List<Type> typeargtypes,
2786                                  MethodCheck methodCheck,
2787                                  InferenceContext inferenceContext,
2788                                  AttrMode mode) {
2789
2790        site = types.capture(site);
2791        ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper(
2792                referenceTree, site, name, argtypes, typeargtypes, VARARITY);
2793
2794        //step 1 - bound lookup
2795        Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
2796        Symbol origBoundSym;
2797        boolean staticErrorForBound = false;
2798        MethodResolutionContext boundSearchResolveContext = new MethodResolutionContext();
2799        boundSearchResolveContext.methodCheck = methodCheck;
2800        Symbol boundSym = origBoundSym = lookupMethod(boundEnv, env.tree.pos(),
2801                site.tsym, boundSearchResolveContext, boundLookupHelper);
2802        SearchResultKind boundSearchResultKind = SearchResultKind.NOT_APPLICABLE_MATCH;
2803        boolean isStaticSelector = TreeInfo.isStaticSelector(referenceTree.expr, names);
2804        boolean shouldCheckForStaticness = isStaticSelector &&
2805                referenceTree.getMode() == ReferenceMode.INVOKE;
2806        if (boundSym.kind != WRONG_MTHS && boundSym.kind != WRONG_MTH) {
2807            if (shouldCheckForStaticness) {
2808                if (!boundSym.isStatic()) {
2809                    staticErrorForBound = true;
2810                    if (hasAnotherApplicableMethod(
2811                            boundSearchResolveContext, boundSym, true)) {
2812                        boundSearchResultKind = SearchResultKind.BAD_MATCH_MORE_SPECIFIC;
2813                    } else {
2814                        boundSearchResultKind = SearchResultKind.BAD_MATCH;
2815                        if (boundSym.kind < ERRONEOUS) {
2816                            boundSym = methodWithCorrectStaticnessNotFound;
2817                        }
2818                    }
2819                } else if (boundSym.kind < ERRONEOUS) {
2820                    boundSearchResultKind = SearchResultKind.GOOD_MATCH;
2821                }
2822            }
2823        }
2824
2825        //step 2 - unbound lookup
2826        Symbol origUnboundSym = null;
2827        Symbol unboundSym = methodNotFound;
2828        ReferenceLookupHelper unboundLookupHelper = null;
2829        Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
2830        SearchResultKind unboundSearchResultKind = SearchResultKind.NOT_APPLICABLE_MATCH;
2831        boolean staticErrorForUnbound = false;
2832        if (isStaticSelector) {
2833            unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext);
2834            MethodResolutionContext unboundSearchResolveContext =
2835                    new MethodResolutionContext();
2836            unboundSearchResolveContext.methodCheck = methodCheck;
2837            unboundSym = origUnboundSym = lookupMethod(unboundEnv, env.tree.pos(),
2838                    site.tsym, unboundSearchResolveContext, unboundLookupHelper);
2839
2840            if (unboundSym.kind != WRONG_MTH && unboundSym.kind != WRONG_MTHS) {
2841                if (shouldCheckForStaticness) {
2842                    if (unboundSym.isStatic()) {
2843                        staticErrorForUnbound = true;
2844                        if (hasAnotherApplicableMethod(
2845                                unboundSearchResolveContext, unboundSym, false)) {
2846                            unboundSearchResultKind = SearchResultKind.BAD_MATCH_MORE_SPECIFIC;
2847                        } else {
2848                            unboundSearchResultKind = SearchResultKind.BAD_MATCH;
2849                            if (unboundSym.kind < ERRONEOUS) {
2850                                unboundSym = methodWithCorrectStaticnessNotFound;
2851                            }
2852                        }
2853                    } else if (unboundSym.kind < ERRONEOUS) {
2854                        unboundSearchResultKind = SearchResultKind.GOOD_MATCH;
2855                    }
2856                }
2857            }
2858        }
2859
2860        //merge results
2861        Pair<Symbol, ReferenceLookupHelper> res;
2862        Symbol bestSym = choose(boundSym, unboundSym);
2863        if (bestSym.kind < ERRONEOUS && (staticErrorForBound || staticErrorForUnbound)) {
2864            if (staticErrorForBound) {
2865                boundSym = methodWithCorrectStaticnessNotFound;
2866            }
2867            if (staticErrorForUnbound) {
2868                unboundSym = methodWithCorrectStaticnessNotFound;
2869            }
2870            bestSym = choose(boundSym, unboundSym);
2871        }
2872        if (bestSym == methodWithCorrectStaticnessNotFound && mode == AttrMode.CHECK) {
2873            Symbol symToPrint = origBoundSym;
2874            String errorFragmentToPrint = "non-static.cant.be.ref";
2875            if (staticErrorForBound && staticErrorForUnbound) {
2876                if (unboundSearchResultKind == SearchResultKind.BAD_MATCH_MORE_SPECIFIC) {
2877                    symToPrint = origUnboundSym;
2878                    errorFragmentToPrint = "static.method.in.unbound.lookup";
2879                }
2880            } else {
2881                if (!staticErrorForBound) {
2882                    symToPrint = origUnboundSym;
2883                    errorFragmentToPrint = "static.method.in.unbound.lookup";
2884                }
2885            }
2886            log.error(referenceTree.expr.pos(), "invalid.mref",
2887                Kinds.kindName(referenceTree.getMode()),
2888                diags.fragment(errorFragmentToPrint,
2889                Kinds.kindName(symToPrint), symToPrint));
2890        }
2891        res = new Pair<>(bestSym,
2892                bestSym == unboundSym ? unboundLookupHelper : boundLookupHelper);
2893        env.info.pendingResolutionPhase = bestSym == unboundSym ?
2894                unboundEnv.info.pendingResolutionPhase :
2895                boundEnv.info.pendingResolutionPhase;
2896
2897        return res;
2898    }
2899
2900    enum SearchResultKind {
2901        GOOD_MATCH,                 //type I
2902        BAD_MATCH_MORE_SPECIFIC,    //type II
2903        BAD_MATCH,                  //type III
2904        NOT_APPLICABLE_MATCH        //type IV
2905    }
2906
2907    boolean hasAnotherApplicableMethod(MethodResolutionContext resolutionContext,
2908            Symbol bestSoFar, boolean staticMth) {
2909        for (Candidate c : resolutionContext.candidates) {
2910            if (resolutionContext.step != c.step ||
2911                !c.isApplicable() ||
2912                c.sym == bestSoFar) {
2913                continue;
2914            } else {
2915                if (c.sym.isStatic() == staticMth) {
2916                    return true;
2917                }
2918            }
2919        }
2920        return false;
2921    }
2922
2923    //where
2924        private Symbol choose(Symbol boundSym, Symbol unboundSym) {
2925            if (lookupSuccess(boundSym) && lookupSuccess(unboundSym)) {
2926                return ambiguityError(boundSym, unboundSym);
2927            } else if (lookupSuccess(boundSym) ||
2928                    (canIgnore(unboundSym) && !canIgnore(boundSym))) {
2929                return boundSym;
2930            } else if (lookupSuccess(unboundSym) ||
2931                    (canIgnore(boundSym) && !canIgnore(unboundSym))) {
2932                return unboundSym;
2933            } else {
2934                return boundSym;
2935            }
2936        }
2937
2938        private boolean lookupSuccess(Symbol s) {
2939            return s.kind == MTH || s.kind == AMBIGUOUS;
2940        }
2941
2942        private boolean canIgnore(Symbol s) {
2943            switch (s.kind) {
2944                case ABSENT_MTH:
2945                    return true;
2946                case WRONG_MTH:
2947                    InapplicableSymbolError errSym =
2948                            (InapplicableSymbolError)s.baseSymbol();
2949                    return new Template(MethodCheckDiag.ARITY_MISMATCH.regex())
2950                            .matches(errSym.errCandidate().snd);
2951                case WRONG_MTHS:
2952                    InapplicableSymbolsError errSyms =
2953                            (InapplicableSymbolsError)s.baseSymbol();
2954                    return errSyms.filterCandidates(errSyms.mapCandidates()).isEmpty();
2955                case WRONG_STATICNESS:
2956                    return false;
2957                default:
2958                    return false;
2959            }
2960        }
2961
2962    /**
2963     * Helper for defining custom method-like lookup logic; a lookup helper
2964     * provides hooks for (i) the actual lookup logic and (ii) accessing the
2965     * lookup result (this step might result in compiler diagnostics to be generated)
2966     */
2967    abstract class LookupHelper {
2968
2969        /** name of the symbol to lookup */
2970        Name name;
2971
2972        /** location in which the lookup takes place */
2973        Type site;
2974
2975        /** actual types used during the lookup */
2976        List<Type> argtypes;
2977
2978        /** type arguments used during the lookup */
2979        List<Type> typeargtypes;
2980
2981        /** Max overload resolution phase handled by this helper */
2982        MethodResolutionPhase maxPhase;
2983
2984        LookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2985            this.name = name;
2986            this.site = site;
2987            this.argtypes = argtypes;
2988            this.typeargtypes = typeargtypes;
2989            this.maxPhase = maxPhase;
2990        }
2991
2992        /**
2993         * Should lookup stop at given phase with given result
2994         */
2995        final boolean shouldStop(Symbol sym, MethodResolutionPhase phase) {
2996            return phase.ordinal() > maxPhase.ordinal() ||
2997                    sym.kind < ERRONEOUS || sym.kind == AMBIGUOUS;
2998        }
2999
3000        /**
3001         * Search for a symbol under a given overload resolution phase - this method
3002         * is usually called several times, once per each overload resolution phase
3003         */
3004        abstract Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase);
3005
3006        /**
3007         * Dump overload resolution info
3008         */
3009        void debug(DiagnosticPosition pos, Symbol sym) {
3010            //do nothing
3011        }
3012
3013        /**
3014         * Validate the result of the lookup
3015         */
3016        abstract Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym);
3017    }
3018
3019    abstract class BasicLookupHelper extends LookupHelper {
3020
3021        BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) {
3022            this(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY);
3023        }
3024
3025        BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3026            super(name, site, argtypes, typeargtypes, maxPhase);
3027        }
3028
3029        @Override
3030        final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3031            Symbol sym = doLookup(env, phase);
3032            if (sym.kind == AMBIGUOUS) {
3033                AmbiguityError a_err = (AmbiguityError)sym.baseSymbol();
3034                sym = a_err.mergeAbstracts(site);
3035            }
3036            return sym;
3037        }
3038
3039        abstract Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase);
3040
3041        @Override
3042        Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3043            if (sym.kind >= AMBIGUOUS) {
3044                //if nothing is found return the 'first' error
3045                sym = accessMethod(sym, pos, location, site, name, true, argtypes, typeargtypes);
3046            }
3047            return sym;
3048        }
3049
3050        @Override
3051        void debug(DiagnosticPosition pos, Symbol sym) {
3052            reportVerboseResolutionDiagnostic(pos, name, site, argtypes, typeargtypes, sym);
3053        }
3054    }
3055
3056    /**
3057     * Helper class for member reference lookup. A reference lookup helper
3058     * defines the basic logic for member reference lookup; a method gives
3059     * access to an 'unbound' helper used to perform an unbound member
3060     * reference lookup.
3061     */
3062    abstract class ReferenceLookupHelper extends LookupHelper {
3063
3064        /** The member reference tree */
3065        JCMemberReference referenceTree;
3066
3067        ReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3068                List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3069            super(name, site, argtypes, typeargtypes, maxPhase);
3070            this.referenceTree = referenceTree;
3071        }
3072
3073        /**
3074         * Returns an unbound version of this lookup helper. By default, this
3075         * method returns an dummy lookup helper.
3076         */
3077        ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3078            //dummy loopkup helper that always return 'methodNotFound'
3079            return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
3080                @Override
3081                ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3082                    return this;
3083                }
3084                @Override
3085                Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3086                    return methodNotFound;
3087                }
3088                @Override
3089                ReferenceKind referenceKind(Symbol sym) {
3090                    Assert.error();
3091                    return null;
3092                }
3093            };
3094        }
3095
3096        /**
3097         * Get the kind of the member reference
3098         */
3099        abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym);
3100
3101        Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3102            if (sym.kind == AMBIGUOUS) {
3103                AmbiguityError a_err = (AmbiguityError)sym.baseSymbol();
3104                sym = a_err.mergeAbstracts(site);
3105            }
3106            //skip error reporting
3107            return sym;
3108        }
3109    }
3110
3111    /**
3112     * Helper class for method reference lookup. The lookup logic is based
3113     * upon Resolve.findMethod; in certain cases, this helper class has a
3114     * corresponding unbound helper class (see UnboundMethodReferenceLookupHelper).
3115     * In such cases, non-static lookup results are thrown away.
3116     */
3117    class MethodReferenceLookupHelper extends ReferenceLookupHelper {
3118
3119        MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3120                List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3121            super(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
3122        }
3123
3124        @Override
3125        final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3126            return findMethod(env, site, name, argtypes, typeargtypes,
3127                    phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
3128        }
3129
3130        @Override
3131        ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3132            if (TreeInfo.isStaticSelector(referenceTree.expr, names) &&
3133                    argtypes.nonEmpty() &&
3134                    (argtypes.head.hasTag(NONE) ||
3135                    types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), site))) {
3136                return new UnboundMethodReferenceLookupHelper(referenceTree, name,
3137                        site, argtypes, typeargtypes, maxPhase);
3138            } else {
3139                return super.unboundLookup(inferenceContext);
3140            }
3141        }
3142
3143        @Override
3144        ReferenceKind referenceKind(Symbol sym) {
3145            if (sym.isStatic()) {
3146                return ReferenceKind.STATIC;
3147            } else {
3148                Name selName = TreeInfo.name(referenceTree.getQualifierExpression());
3149                return selName != null && selName == names._super ?
3150                        ReferenceKind.SUPER :
3151                        ReferenceKind.BOUND;
3152            }
3153        }
3154    }
3155
3156    /**
3157     * Helper class for unbound method reference lookup. Essentially the same
3158     * as the basic method reference lookup helper; main difference is that static
3159     * lookup results are thrown away. If qualifier type is raw, an attempt to
3160     * infer a parameterized type is made using the first actual argument (that
3161     * would otherwise be ignored during the lookup).
3162     */
3163    class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper {
3164
3165        UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3166                List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3167            super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase);
3168            if (site.isRaw() && !argtypes.head.hasTag(NONE)) {
3169                Type asSuperSite = types.asSuper(argtypes.head, site.tsym);
3170                this.site = asSuperSite;
3171            }
3172        }
3173
3174        @Override
3175        ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3176            return this;
3177        }
3178
3179        @Override
3180        ReferenceKind referenceKind(Symbol sym) {
3181            return ReferenceKind.UNBOUND;
3182        }
3183    }
3184
3185    /**
3186     * Helper class for array constructor lookup; an array constructor lookup
3187     * is simulated by looking up a method that returns the array type specified
3188     * as qualifier, and that accepts a single int parameter (size of the array).
3189     */
3190    class ArrayConstructorReferenceLookupHelper extends ReferenceLookupHelper {
3191
3192        ArrayConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
3193                List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3194            super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
3195        }
3196
3197        @Override
3198        protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3199            WriteableScope sc = WriteableScope.create(syms.arrayClass);
3200            MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym);
3201            arrayConstr.type = new MethodType(List.<Type>of(syms.intType), site, List.<Type>nil(), syms.methodClass);
3202            sc.enter(arrayConstr);
3203            return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false, false);
3204        }
3205
3206        @Override
3207        ReferenceKind referenceKind(Symbol sym) {
3208            return ReferenceKind.ARRAY_CTOR;
3209        }
3210    }
3211
3212    /**
3213     * Helper class for constructor reference lookup. The lookup logic is based
3214     * upon either Resolve.findMethod or Resolve.findDiamond - depending on
3215     * whether the constructor reference needs diamond inference (this is the case
3216     * if the qualifier type is raw). A special erroneous symbol is returned
3217     * if the lookup returns the constructor of an inner class and there's no
3218     * enclosing instance in scope.
3219     */
3220    class ConstructorReferenceLookupHelper extends ReferenceLookupHelper {
3221
3222        boolean needsInference;
3223
3224        ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
3225                List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3226            super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
3227            if (site.isRaw()) {
3228                this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym, site.getMetadata());
3229                needsInference = true;
3230            }
3231        }
3232
3233        @Override
3234        protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3235            Symbol sym = needsInference ?
3236                findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
3237                findMethod(env, site, name, argtypes, typeargtypes,
3238                        phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
3239            return sym.kind != MTH ||
3240                          site.getEnclosingType().hasTag(NONE) ||
3241                          hasEnclosingInstance(env, site) ?
3242                          sym : new InvalidSymbolError(Kinds.MISSING_ENCL, sym, null) {
3243                    @Override
3244                    JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
3245                       return diags.create(dkind, log.currentSource(), pos,
3246                            "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType());
3247                    }
3248                };
3249        }
3250
3251        @Override
3252        ReferenceKind referenceKind(Symbol sym) {
3253            return site.getEnclosingType().hasTag(NONE) ?
3254                    ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER;
3255        }
3256    }
3257
3258    /**
3259     * Main overload resolution routine. On each overload resolution step, a
3260     * lookup helper class is used to perform the method/constructor lookup;
3261     * at the end of the lookup, the helper is used to validate the results
3262     * (this last step might trigger overload resolution diagnostics).
3263     */
3264    Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, MethodCheck methodCheck, LookupHelper lookupHelper) {
3265        MethodResolutionContext resolveContext = new MethodResolutionContext();
3266        resolveContext.methodCheck = methodCheck;
3267        return lookupMethod(env, pos, location, resolveContext, lookupHelper);
3268    }
3269
3270    Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location,
3271            MethodResolutionContext resolveContext, LookupHelper lookupHelper) {
3272        MethodResolutionContext prevResolutionContext = currentResolutionContext;
3273        try {
3274            Symbol bestSoFar = methodNotFound;
3275            currentResolutionContext = resolveContext;
3276            for (MethodResolutionPhase phase : methodResolutionSteps) {
3277                if (lookupHelper.shouldStop(bestSoFar, phase))
3278                    break;
3279                MethodResolutionPhase prevPhase = currentResolutionContext.step;
3280                Symbol prevBest = bestSoFar;
3281                currentResolutionContext.step = phase;
3282                Symbol sym = lookupHelper.lookup(env, phase);
3283                lookupHelper.debug(pos, sym);
3284                bestSoFar = phase.mergeResults(bestSoFar, sym);
3285                env.info.pendingResolutionPhase = (prevBest == bestSoFar) ? prevPhase : phase;
3286            }
3287            return lookupHelper.access(env, pos, location, bestSoFar);
3288        } finally {
3289            currentResolutionContext = prevResolutionContext;
3290        }
3291    }
3292
3293    /**
3294     * Resolve `c.name' where name == this or name == super.
3295     * @param pos           The position to use for error reporting.
3296     * @param env           The environment current at the expression.
3297     * @param c             The qualifier.
3298     * @param name          The identifier's name.
3299     */
3300    Symbol resolveSelf(DiagnosticPosition pos,
3301                       Env<AttrContext> env,
3302                       TypeSymbol c,
3303                       Name name) {
3304        Env<AttrContext> env1 = env;
3305        boolean staticOnly = false;
3306        while (env1.outer != null) {
3307            if (isStatic(env1)) staticOnly = true;
3308            if (env1.enclClass.sym == c) {
3309                Symbol sym = env1.info.scope.findFirst(name);
3310                if (sym != null) {
3311                    if (staticOnly) sym = new StaticError(sym);
3312                    return accessBase(sym, pos, env.enclClass.sym.type,
3313                                  name, true);
3314                }
3315            }
3316            if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3317            env1 = env1.outer;
3318        }
3319        if (c.isInterface() &&
3320            name == names._super && !isStatic(env) &&
3321            types.isDirectSuperInterface(c, env.enclClass.sym)) {
3322            //this might be a default super call if one of the superinterfaces is 'c'
3323            for (Type t : pruneInterfaces(env.enclClass.type)) {
3324                if (t.tsym == c) {
3325                    env.info.defaultSuperCallSite = t;
3326                    return new VarSymbol(0, names._super,
3327                            types.asSuper(env.enclClass.type, c), env.enclClass.sym);
3328                }
3329            }
3330            //find a direct superinterface that is a subtype of 'c'
3331            for (Type i : types.interfaces(env.enclClass.type)) {
3332                if (i.tsym.isSubClass(c, types) && i.tsym != c) {
3333                    log.error(pos, "illegal.default.super.call", c,
3334                            diags.fragment("redundant.supertype", c, i));
3335                    return syms.errSymbol;
3336                }
3337            }
3338            Assert.error();
3339        }
3340        log.error(pos, "not.encl.class", c);
3341        return syms.errSymbol;
3342    }
3343    //where
3344    private List<Type> pruneInterfaces(Type t) {
3345        ListBuffer<Type> result = new ListBuffer<>();
3346        for (Type t1 : types.interfaces(t)) {
3347            boolean shouldAdd = true;
3348            for (Type t2 : types.interfaces(t)) {
3349                if (t1 != t2 && types.isSubtypeNoCapture(t2, t1)) {
3350                    shouldAdd = false;
3351                }
3352            }
3353            if (shouldAdd) {
3354                result.append(t1);
3355            }
3356        }
3357        return result.toList();
3358    }
3359
3360
3361    /**
3362     * Resolve `c.this' for an enclosing class c that contains the
3363     * named member.
3364     * @param pos           The position to use for error reporting.
3365     * @param env           The environment current at the expression.
3366     * @param member        The member that must be contained in the result.
3367     */
3368    Symbol resolveSelfContaining(DiagnosticPosition pos,
3369                                 Env<AttrContext> env,
3370                                 Symbol member,
3371                                 boolean isSuperCall) {
3372        Symbol sym = resolveSelfContainingInternal(env, member, isSuperCall);
3373        if (sym == null) {
3374            log.error(pos, "encl.class.required", member);
3375            return syms.errSymbol;
3376        } else {
3377            return accessBase(sym, pos, env.enclClass.sym.type, sym.name, true);
3378        }
3379    }
3380
3381    boolean hasEnclosingInstance(Env<AttrContext> env, Type type) {
3382        Symbol encl = resolveSelfContainingInternal(env, type.tsym, false);
3383        return encl != null && encl.kind < ERRONEOUS;
3384    }
3385
3386    private Symbol resolveSelfContainingInternal(Env<AttrContext> env,
3387                                 Symbol member,
3388                                 boolean isSuperCall) {
3389        Name name = names._this;
3390        Env<AttrContext> env1 = isSuperCall ? env.outer : env;
3391        boolean staticOnly = false;
3392        if (env1 != null) {
3393            while (env1 != null && env1.outer != null) {
3394                if (isStatic(env1)) staticOnly = true;
3395                if (env1.enclClass.sym.isSubClass(member.owner, types)) {
3396                    Symbol sym = env1.info.scope.findFirst(name);
3397                    if (sym != null) {
3398                        if (staticOnly) sym = new StaticError(sym);
3399                        return sym;
3400                    }
3401                }
3402                if ((env1.enclClass.sym.flags() & STATIC) != 0)
3403                    staticOnly = true;
3404                env1 = env1.outer;
3405            }
3406        }
3407        return null;
3408    }
3409
3410    /**
3411     * Resolve an appropriate implicit this instance for t's container.
3412     * JLS 8.8.5.1 and 15.9.2
3413     */
3414    Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) {
3415        return resolveImplicitThis(pos, env, t, false);
3416    }
3417
3418    Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t, boolean isSuperCall) {
3419        Type thisType = (((t.tsym.owner.kind & (MTH|VAR)) != 0)
3420                         ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this)
3421                         : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type;
3422        if (env.info.isSelfCall && thisType.tsym == env.enclClass.sym)
3423            log.error(pos, "cant.ref.before.ctor.called", "this");
3424        return thisType;
3425    }
3426
3427/* ***************************************************************************
3428 *  ResolveError classes, indicating error situations when accessing symbols
3429 ****************************************************************************/
3430
3431    //used by TransTypes when checking target type of synthetic cast
3432    public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
3433        AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
3434        logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
3435    }
3436    //where
3437    private void logResolveError(ResolveError error,
3438            DiagnosticPosition pos,
3439            Symbol location,
3440            Type site,
3441            Name name,
3442            List<Type> argtypes,
3443            List<Type> typeargtypes) {
3444        JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
3445                pos, location, site, name, argtypes, typeargtypes);
3446        if (d != null) {
3447            d.setFlag(DiagnosticFlag.RESOLVE_ERROR);
3448            log.report(d);
3449        }
3450    }
3451
3452    private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
3453
3454    public Object methodArguments(List<Type> argtypes) {
3455        if (argtypes == null || argtypes.isEmpty()) {
3456            return noArgs;
3457        } else {
3458            ListBuffer<Object> diagArgs = new ListBuffer<>();
3459            for (Type t : argtypes) {
3460                if (t.hasTag(DEFERRED)) {
3461                    diagArgs.append(((DeferredAttr.DeferredType)t).tree);
3462                } else {
3463                    diagArgs.append(t);
3464                }
3465            }
3466            return diagArgs;
3467        }
3468    }
3469
3470    /**
3471     * Root class for resolution errors. Subclass of ResolveError
3472     * represent a different kinds of resolution error - as such they must
3473     * specify how they map into concrete compiler diagnostics.
3474     */
3475    abstract class ResolveError extends Symbol {
3476
3477        /** The name of the kind of error, for debugging only. */
3478        final String debugName;
3479
3480        ResolveError(int kind, String debugName) {
3481            super(kind, 0, null, null, null);
3482            this.debugName = debugName;
3483        }
3484
3485        @Override @DefinedBy(Api.LANGUAGE_MODEL)
3486        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
3487            throw new AssertionError();
3488        }
3489
3490        @Override
3491        public String toString() {
3492            return debugName;
3493        }
3494
3495        @Override
3496        public boolean exists() {
3497            return false;
3498        }
3499
3500        @Override
3501        public boolean isStatic() {
3502            return false;
3503        }
3504
3505        /**
3506         * Create an external representation for this erroneous symbol to be
3507         * used during attribution - by default this returns the symbol of a
3508         * brand new error type which stores the original type found
3509         * during resolution.
3510         *
3511         * @param name     the name used during resolution
3512         * @param location the location from which the symbol is accessed
3513         */
3514        protected Symbol access(Name name, TypeSymbol location) {
3515            return types.createErrorType(name, location, syms.errSymbol.type).tsym;
3516        }
3517
3518        /**
3519         * Create a diagnostic representing this resolution error.
3520         *
3521         * @param dkind     The kind of the diagnostic to be created (e.g error).
3522         * @param pos       The position to be used for error reporting.
3523         * @param site      The original type from where the selection took place.
3524         * @param name      The name of the symbol to be resolved.
3525         * @param argtypes  The invocation's value arguments,
3526         *                  if we looked for a method.
3527         * @param typeargtypes  The invocation's type arguments,
3528         *                      if we looked for a method.
3529         */
3530        abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3531                DiagnosticPosition pos,
3532                Symbol location,
3533                Type site,
3534                Name name,
3535                List<Type> argtypes,
3536                List<Type> typeargtypes);
3537    }
3538
3539    /**
3540     * This class is the root class of all resolution errors caused by
3541     * an invalid symbol being found during resolution.
3542     */
3543    abstract class InvalidSymbolError extends ResolveError {
3544
3545        /** The invalid symbol found during resolution */
3546        Symbol sym;
3547
3548        InvalidSymbolError(int kind, Symbol sym, String debugName) {
3549            super(kind, debugName);
3550            this.sym = sym;
3551        }
3552
3553        @Override
3554        public boolean exists() {
3555            return true;
3556        }
3557
3558        @Override
3559        public String toString() {
3560             return super.toString() + " wrongSym=" + sym;
3561        }
3562
3563        @Override
3564        public Symbol access(Name name, TypeSymbol location) {
3565            if ((sym.kind & ERRONEOUS) == 0 && (sym.kind & TYP) != 0)
3566                return types.createErrorType(name, location, sym.type).tsym;
3567            else
3568                return sym;
3569        }
3570    }
3571
3572    /**
3573     * InvalidSymbolError error class indicating that a symbol matching a
3574     * given name does not exists in a given site.
3575     */
3576    class SymbolNotFoundError extends ResolveError {
3577
3578        SymbolNotFoundError(int kind) {
3579            this(kind, "symbol not found error");
3580        }
3581
3582        SymbolNotFoundError(int kind, String debugName) {
3583            super(kind, debugName);
3584        }
3585
3586        @Override
3587        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3588                DiagnosticPosition pos,
3589                Symbol location,
3590                Type site,
3591                Name name,
3592                List<Type> argtypes,
3593                List<Type> typeargtypes) {
3594            argtypes = argtypes == null ? List.<Type>nil() : argtypes;
3595            typeargtypes = typeargtypes == null ? List.<Type>nil() : typeargtypes;
3596            if (name == names.error)
3597                return null;
3598
3599            if (syms.operatorNames.contains(name)) {
3600                boolean isUnaryOp = argtypes.size() == 1;
3601                String key = argtypes.size() == 1 ?
3602                    "operator.cant.be.applied" :
3603                    "operator.cant.be.applied.1";
3604                Type first = argtypes.head;
3605                Type second = !isUnaryOp ? argtypes.tail.head : null;
3606                return diags.create(dkind, log.currentSource(), pos,
3607                        key, name, first, second);
3608            }
3609            boolean hasLocation = false;
3610            if (location == null) {
3611                location = site.tsym;
3612            }
3613            if (!location.name.isEmpty()) {
3614                if (location.kind == PCK && !site.tsym.exists()) {
3615                    return diags.create(dkind, log.currentSource(), pos,
3616                        "doesnt.exist", location);
3617                }
3618                hasLocation = !location.name.equals(names._this) &&
3619                        !location.name.equals(names._super);
3620            }
3621            boolean isConstructor = (kind == ABSENT_MTH || kind == WRONG_STATICNESS) &&
3622                    name == names.init;
3623            KindName kindname = isConstructor ? KindName.CONSTRUCTOR : absentKind(kind);
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(int 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            if (syms.operatorNames.contains(name)) {
3710                boolean isUnaryOp = argtypes.size() == 1;
3711                String key = argtypes.size() == 1 ?
3712                    "operator.cant.be.applied" :
3713                    "operator.cant.be.applied.1";
3714                Type first = argtypes.head;
3715                Type second = !isUnaryOp ? argtypes.tail.head : null;
3716                return diags.create(dkind, log.currentSource(), pos,
3717                        key, name, first, second);
3718            }
3719            else {
3720                Pair<Symbol, JCDiagnostic> c = errCandidate();
3721                if (compactMethodDiags) {
3722                    for (Map.Entry<Template, DiagnosticRewriter> _entry :
3723                            MethodResolutionDiagHelper.rewriters.entrySet()) {
3724                        if (_entry.getKey().matches(c.snd)) {
3725                            JCDiagnostic simpleDiag =
3726                                    _entry.getValue().rewriteDiagnostic(diags, pos,
3727                                        log.currentSource(), dkind, c.snd);
3728                            simpleDiag.setFlag(DiagnosticFlag.COMPRESSED);
3729                            return simpleDiag;
3730                        }
3731                    }
3732                }
3733                Symbol ws = c.fst.asMemberOf(site, types);
3734                return diags.create(dkind, log.currentSource(), pos,
3735                          "cant.apply.symbol",
3736                          kindName(ws),
3737                          ws.name == names.init ? ws.owner.name : ws.name,
3738                          methodArguments(ws.type.getParameterTypes()),
3739                          methodArguments(argtypes),
3740                          kindName(ws.owner),
3741                          ws.owner.type,
3742                          c.snd);
3743            }
3744        }
3745
3746        @Override
3747        public Symbol access(Name name, TypeSymbol location) {
3748            return types.createErrorType(name, location, syms.errSymbol.type).tsym;
3749        }
3750
3751        protected Pair<Symbol, JCDiagnostic> errCandidate() {
3752            Candidate bestSoFar = null;
3753            for (Candidate c : resolveContext.candidates) {
3754                if (c.isApplicable()) continue;
3755                bestSoFar = c;
3756            }
3757            Assert.checkNonNull(bestSoFar);
3758            return new Pair<>(bestSoFar.sym, bestSoFar.details);
3759        }
3760    }
3761
3762    /**
3763     * ResolveError error class indicating that a set of symbols
3764     * (either methods, constructors or operands) is not applicable
3765     * given an actual arguments/type argument list.
3766     */
3767    class InapplicableSymbolsError extends InapplicableSymbolError {
3768
3769        InapplicableSymbolsError(MethodResolutionContext context) {
3770            super(WRONG_MTHS, "inapplicable symbols", context);
3771        }
3772
3773        @Override
3774        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3775                DiagnosticPosition pos,
3776                Symbol location,
3777                Type site,
3778                Name name,
3779                List<Type> argtypes,
3780                List<Type> typeargtypes) {
3781            Map<Symbol, JCDiagnostic> candidatesMap = mapCandidates();
3782            Map<Symbol, JCDiagnostic> filteredCandidates = compactMethodDiags ?
3783                    filterCandidates(candidatesMap) :
3784                    mapCandidates();
3785            if (filteredCandidates.isEmpty()) {
3786                filteredCandidates = candidatesMap;
3787            }
3788            boolean truncatedDiag = candidatesMap.size() != filteredCandidates.size();
3789            if (filteredCandidates.size() > 1) {
3790                JCDiagnostic err = diags.create(dkind,
3791                        null,
3792                        truncatedDiag ?
3793                            EnumSet.of(DiagnosticFlag.COMPRESSED) :
3794                            EnumSet.noneOf(DiagnosticFlag.class),
3795                        log.currentSource(),
3796                        pos,
3797                        "cant.apply.symbols",
3798                        name == names.init ? KindName.CONSTRUCTOR : absentKind(kind),
3799                        name == names.init ? site.tsym.name : name,
3800                        methodArguments(argtypes));
3801                return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(filteredCandidates, site));
3802            } else if (filteredCandidates.size() == 1) {
3803                Map.Entry<Symbol, JCDiagnostic> _e =
3804                                filteredCandidates.entrySet().iterator().next();
3805                final Pair<Symbol, JCDiagnostic> p = new Pair<>(_e.getKey(), _e.getValue());
3806                JCDiagnostic d = new InapplicableSymbolError(resolveContext) {
3807                    @Override
3808                    protected Pair<Symbol, JCDiagnostic> errCandidate() {
3809                        return p;
3810                    }
3811                }.getDiagnostic(dkind, pos,
3812                    location, site, name, argtypes, typeargtypes);
3813                if (truncatedDiag) {
3814                    d.setFlag(DiagnosticFlag.COMPRESSED);
3815                }
3816                return d;
3817            } else {
3818                return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
3819                    location, site, name, argtypes, typeargtypes);
3820            }
3821        }
3822        //where
3823            private Map<Symbol, JCDiagnostic> mapCandidates() {
3824                Map<Symbol, JCDiagnostic> candidates = new LinkedHashMap<>();
3825                for (Candidate c : resolveContext.candidates) {
3826                    if (c.isApplicable()) continue;
3827                    candidates.put(c.sym, c.details);
3828                }
3829                return candidates;
3830            }
3831
3832            Map<Symbol, JCDiagnostic> filterCandidates(Map<Symbol, JCDiagnostic> candidatesMap) {
3833                Map<Symbol, JCDiagnostic> candidates = new LinkedHashMap<>();
3834                for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) {
3835                    JCDiagnostic d = _entry.getValue();
3836                    if (!new Template(MethodCheckDiag.ARITY_MISMATCH.regex()).matches(d)) {
3837                        candidates.put(_entry.getKey(), d);
3838                    }
3839                }
3840                return candidates;
3841            }
3842
3843            private List<JCDiagnostic> candidateDetails(Map<Symbol, JCDiagnostic> candidatesMap, Type site) {
3844                List<JCDiagnostic> details = List.nil();
3845                for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) {
3846                    Symbol sym = _entry.getKey();
3847                    JCDiagnostic detailDiag = diags.fragment("inapplicable.method",
3848                            Kinds.kindName(sym),
3849                            sym.location(site, types),
3850                            sym.asMemberOf(site, types),
3851                            _entry.getValue());
3852                    details = details.prepend(detailDiag);
3853                }
3854                //typically members are visited in reverse order (see Scope)
3855                //so we need to reverse the candidate list so that candidates
3856                //conform to source order
3857                return details;
3858            }
3859    }
3860
3861    /**
3862     * An InvalidSymbolError error class indicating that a symbol is not
3863     * accessible from a given site
3864     */
3865    class AccessError extends InvalidSymbolError {
3866
3867        private Env<AttrContext> env;
3868        private Type site;
3869
3870        AccessError(Symbol sym) {
3871            this(null, null, sym);
3872        }
3873
3874        AccessError(Env<AttrContext> env, Type site, Symbol sym) {
3875            super(HIDDEN, sym, "access error");
3876            this.env = env;
3877            this.site = site;
3878            if (debugResolve)
3879                log.error("proc.messager", sym + " @ " + site + " is inaccessible.");
3880        }
3881
3882        @Override
3883        public boolean exists() {
3884            return false;
3885        }
3886
3887        @Override
3888        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3889                DiagnosticPosition pos,
3890                Symbol location,
3891                Type site,
3892                Name name,
3893                List<Type> argtypes,
3894                List<Type> typeargtypes) {
3895            if (sym.owner.type.hasTag(ERROR))
3896                return null;
3897
3898            if (sym.name == names.init && sym.owner != site.tsym) {
3899                return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind,
3900                        pos, location, site, name, argtypes, typeargtypes);
3901            }
3902            else if ((sym.flags() & PUBLIC) != 0
3903                || (env != null && this.site != null
3904                    && !isAccessible(env, this.site))) {
3905                return diags.create(dkind, log.currentSource(),
3906                        pos, "not.def.access.class.intf.cant.access",
3907                    sym, sym.location());
3908            }
3909            else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) {
3910                return diags.create(dkind, log.currentSource(),
3911                        pos, "report.access", sym,
3912                        asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
3913                        sym.location());
3914            }
3915            else {
3916                return diags.create(dkind, log.currentSource(),
3917                        pos, "not.def.public.cant.access", sym, sym.location());
3918            }
3919        }
3920    }
3921
3922    /**
3923     * InvalidSymbolError error class indicating that an instance member
3924     * has erroneously been accessed from a static context.
3925     */
3926    class StaticError extends InvalidSymbolError {
3927
3928        StaticError(Symbol sym) {
3929            super(STATICERR, sym, "static error");
3930        }
3931
3932        @Override
3933        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3934                DiagnosticPosition pos,
3935                Symbol location,
3936                Type site,
3937                Name name,
3938                List<Type> argtypes,
3939                List<Type> typeargtypes) {
3940            Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS))
3941                ? types.erasure(sym.type).tsym
3942                : sym);
3943            return diags.create(dkind, log.currentSource(), pos,
3944                    "non-static.cant.be.ref", kindName(sym), errSym);
3945        }
3946    }
3947
3948    /**
3949     * InvalidSymbolError error class indicating that a pair of symbols
3950     * (either methods, constructors or operands) are ambiguous
3951     * given an actual arguments/type argument list.
3952     */
3953    class AmbiguityError extends ResolveError {
3954
3955        /** The other maximally specific symbol */
3956        List<Symbol> ambiguousSyms = List.nil();
3957
3958        @Override
3959        public boolean exists() {
3960            return true;
3961        }
3962
3963        AmbiguityError(Symbol sym1, Symbol sym2) {
3964            super(AMBIGUOUS, "ambiguity error");
3965            ambiguousSyms = flatten(sym2).appendList(flatten(sym1));
3966        }
3967
3968        private List<Symbol> flatten(Symbol sym) {
3969            if (sym.kind == AMBIGUOUS) {
3970                return ((AmbiguityError)sym.baseSymbol()).ambiguousSyms;
3971            } else {
3972                return List.of(sym);
3973            }
3974        }
3975
3976        AmbiguityError addAmbiguousSymbol(Symbol s) {
3977            ambiguousSyms = ambiguousSyms.prepend(s);
3978            return this;
3979        }
3980
3981        @Override
3982        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3983                DiagnosticPosition pos,
3984                Symbol location,
3985                Type site,
3986                Name name,
3987                List<Type> argtypes,
3988                List<Type> typeargtypes) {
3989            List<Symbol> diagSyms = ambiguousSyms.reverse();
3990            Symbol s1 = diagSyms.head;
3991            Symbol s2 = diagSyms.tail.head;
3992            Name sname = s1.name;
3993            if (sname == names.init) sname = s1.owner.name;
3994            return diags.create(dkind, log.currentSource(),
3995                      pos, "ref.ambiguous", sname,
3996                      kindName(s1),
3997                      s1,
3998                      s1.location(site, types),
3999                      kindName(s2),
4000                      s2,
4001                      s2.location(site, types));
4002        }
4003
4004        /**
4005         * If multiple applicable methods are found during overload and none of them
4006         * is more specific than the others, attempt to merge their signatures.
4007         */
4008        Symbol mergeAbstracts(Type site) {
4009            List<Symbol> ambiguousInOrder = ambiguousSyms.reverse();
4010            for (Symbol s : ambiguousInOrder) {
4011                Type mt = types.memberType(site, s);
4012                boolean found = true;
4013                List<Type> allThrown = mt.getThrownTypes();
4014                for (Symbol s2 : ambiguousInOrder) {
4015                    Type mt2 = types.memberType(site, s2);
4016                    if ((s2.flags() & ABSTRACT) == 0 ||
4017                        !types.overrideEquivalent(mt, mt2) ||
4018                        !types.isSameTypes(s.erasure(types).getParameterTypes(),
4019                                       s2.erasure(types).getParameterTypes())) {
4020                        //ambiguity cannot be resolved
4021                        return this;
4022                    }
4023                    Type mst = mostSpecificReturnType(mt, mt2);
4024                    if (mst == null || mst != mt) {
4025                        found = false;
4026                        break;
4027                    }
4028                    allThrown = chk.intersect(allThrown, mt2.getThrownTypes());
4029                }
4030                if (found) {
4031                    //all ambiguous methods were abstract and one method had
4032                    //most specific return type then others
4033                    return (allThrown == mt.getThrownTypes()) ?
4034                            s : new MethodSymbol(
4035                                s.flags(),
4036                                s.name,
4037                                types.createMethodTypeWithThrown(mt, allThrown),
4038                                s.owner);
4039                }
4040            }
4041            return this;
4042        }
4043
4044        @Override
4045        protected Symbol access(Name name, TypeSymbol location) {
4046            Symbol firstAmbiguity = ambiguousSyms.last();
4047            return firstAmbiguity.kind == TYP ?
4048                    types.createErrorType(name, location, firstAmbiguity.type).tsym :
4049                    firstAmbiguity;
4050        }
4051    }
4052
4053    class BadVarargsMethod extends ResolveError {
4054
4055        ResolveError delegatedError;
4056
4057        BadVarargsMethod(ResolveError delegatedError) {
4058            super(delegatedError.kind, "badVarargs");
4059            this.delegatedError = delegatedError;
4060        }
4061
4062        @Override
4063        public Symbol baseSymbol() {
4064            return delegatedError.baseSymbol();
4065        }
4066
4067        @Override
4068        protected Symbol access(Name name, TypeSymbol location) {
4069            return delegatedError.access(name, location);
4070        }
4071
4072        @Override
4073        public boolean exists() {
4074            return true;
4075        }
4076
4077        @Override
4078        JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4079            return delegatedError.getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes);
4080        }
4081    }
4082
4083    /**
4084     * Helper class for method resolution diagnostic simplification.
4085     * Certain resolution diagnostic are rewritten as simpler diagnostic
4086     * where the enclosing resolution diagnostic (i.e. 'inapplicable method')
4087     * is stripped away, as it doesn't carry additional info. The logic
4088     * for matching a given diagnostic is given in terms of a template
4089     * hierarchy: a diagnostic template can be specified programmatically,
4090     * so that only certain diagnostics are matched. Each templete is then
4091     * associated with a rewriter object that carries out the task of rewtiting
4092     * the diagnostic to a simpler one.
4093     */
4094    static class MethodResolutionDiagHelper {
4095
4096        /**
4097         * A diagnostic rewriter transforms a method resolution diagnostic
4098         * into a simpler one
4099         */
4100        interface DiagnosticRewriter {
4101            JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
4102                    DiagnosticPosition preferedPos, DiagnosticSource preferredSource,
4103                    DiagnosticType preferredKind, JCDiagnostic d);
4104        }
4105
4106        /**
4107         * A diagnostic template is made up of two ingredients: (i) a regular
4108         * expression for matching a diagnostic key and (ii) a list of sub-templates
4109         * for matching diagnostic arguments.
4110         */
4111        static class Template {
4112
4113            /** regex used to match diag key */
4114            String regex;
4115
4116            /** templates used to match diagnostic args */
4117            Template[] subTemplates;
4118
4119            Template(String key, Template... subTemplates) {
4120                this.regex = key;
4121                this.subTemplates = subTemplates;
4122            }
4123
4124            /**
4125             * Returns true if the regex matches the diagnostic key and if
4126             * all diagnostic arguments are matches by corresponding sub-templates.
4127             */
4128            boolean matches(Object o) {
4129                JCDiagnostic d = (JCDiagnostic)o;
4130                Object[] args = d.getArgs();
4131                if (!d.getCode().matches(regex) ||
4132                        subTemplates.length != d.getArgs().length) {
4133                    return false;
4134                }
4135                for (int i = 0; i < args.length ; i++) {
4136                    if (!subTemplates[i].matches(args[i])) {
4137                        return false;
4138                    }
4139                }
4140                return true;
4141            }
4142        }
4143
4144        /** a dummy template that match any diagnostic argument */
4145        static final Template skip = new Template("") {
4146            @Override
4147            boolean matches(Object d) {
4148                return true;
4149            }
4150        };
4151
4152        /** rewriter map used for method resolution simplification */
4153        static final Map<Template, DiagnosticRewriter> rewriters = new LinkedHashMap<>();
4154
4155        static {
4156            String argMismatchRegex = MethodCheckDiag.ARG_MISMATCH.regex();
4157            rewriters.put(new Template(argMismatchRegex, skip),
4158                    new DiagnosticRewriter() {
4159                @Override
4160                public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
4161                        DiagnosticPosition preferedPos, DiagnosticSource preferredSource,
4162                        DiagnosticType preferredKind, JCDiagnostic d) {
4163                    JCDiagnostic cause = (JCDiagnostic)d.getArgs()[0];
4164                    return diags.create(preferredKind, preferredSource, d.getDiagnosticPosition(),
4165                            "prob.found.req", cause);
4166                }
4167            });
4168        }
4169    }
4170
4171    enum MethodResolutionPhase {
4172        BASIC(false, false),
4173        BOX(true, false),
4174        VARARITY(true, true) {
4175            @Override
4176            public Symbol mergeResults(Symbol bestSoFar, Symbol sym) {
4177                //Check invariants (see {@code LookupHelper.shouldStop})
4178                Assert.check(bestSoFar.kind >= ERRONEOUS && bestSoFar.kind != AMBIGUOUS);
4179                if (sym.kind < ERRONEOUS) {
4180                    //varargs resolution successful
4181                    return sym;
4182                } else {
4183                    //pick best error
4184                    switch (bestSoFar.kind) {
4185                        case WRONG_MTH:
4186                        case WRONG_MTHS:
4187                            //Override previous errors if they were caused by argument mismatch.
4188                            //This generally means preferring current symbols - but we need to pay
4189                            //attention to the fact that the varargs lookup returns 'less' candidates
4190                            //than the previous rounds, and adjust that accordingly.
4191                            switch (sym.kind) {
4192                                case WRONG_MTH:
4193                                    //if the previous round matched more than one method, return that
4194                                    //result instead
4195                                    return bestSoFar.kind == WRONG_MTHS ?
4196                                            bestSoFar : sym;
4197                                case ABSENT_MTH:
4198                                    //do not override erroneous symbol if the arity lookup did not
4199                                    //match any method
4200                                    return bestSoFar;
4201                                case WRONG_MTHS:
4202                                default:
4203                                    //safe to override
4204                                    return sym;
4205                            }
4206                        default:
4207                            //otherwise, return first error
4208                            return bestSoFar;
4209                    }
4210                }
4211            }
4212        };
4213
4214        final boolean isBoxingRequired;
4215        final boolean isVarargsRequired;
4216
4217        MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) {
4218           this.isBoxingRequired = isBoxingRequired;
4219           this.isVarargsRequired = isVarargsRequired;
4220        }
4221
4222        public boolean isBoxingRequired() {
4223            return isBoxingRequired;
4224        }
4225
4226        public boolean isVarargsRequired() {
4227            return isVarargsRequired;
4228        }
4229
4230        public Symbol mergeResults(Symbol prev, Symbol sym) {
4231            return sym;
4232        }
4233    }
4234
4235    final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
4236
4237    /**
4238     * A resolution context is used to keep track of intermediate results of
4239     * overload resolution, such as list of method that are not applicable
4240     * (used to generate more precise diagnostics) and so on. Resolution contexts
4241     * can be nested - this means that when each overload resolution routine should
4242     * work within the resolution context it created.
4243     */
4244    class MethodResolutionContext {
4245
4246        private List<Candidate> candidates = List.nil();
4247
4248        MethodResolutionPhase step = null;
4249
4250        MethodCheck methodCheck = resolveMethodCheck;
4251
4252        private boolean internalResolution = false;
4253        private DeferredAttr.AttrMode attrMode = DeferredAttr.AttrMode.SPECULATIVE;
4254
4255        void addInapplicableCandidate(Symbol sym, JCDiagnostic details) {
4256            Candidate c = new Candidate(currentResolutionContext.step, sym, details, null);
4257            candidates = candidates.append(c);
4258        }
4259
4260        void addApplicableCandidate(Symbol sym, Type mtype) {
4261            Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype);
4262            candidates = candidates.append(c);
4263        }
4264
4265        DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext, ResultInfo pendingResult, Warner warn) {
4266            DeferredAttrContext parent = (pendingResult == null)
4267                ? deferredAttr.emptyDeferredAttrContext
4268                : pendingResult.checkContext.deferredAttrContext();
4269            return deferredAttr.new DeferredAttrContext(attrMode, sym, step,
4270                    inferenceContext, parent, warn);
4271        }
4272
4273        /**
4274         * This class represents an overload resolution candidate. There are two
4275         * kinds of candidates: applicable methods and inapplicable methods;
4276         * applicable methods have a pointer to the instantiated method type,
4277         * while inapplicable candidates contain further details about the
4278         * reason why the method has been considered inapplicable.
4279         */
4280        @SuppressWarnings("overrides")
4281        class Candidate {
4282
4283            final MethodResolutionPhase step;
4284            final Symbol sym;
4285            final JCDiagnostic details;
4286            final Type mtype;
4287
4288            private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
4289                this.step = step;
4290                this.sym = sym;
4291                this.details = details;
4292                this.mtype = mtype;
4293            }
4294
4295            @Override
4296            public boolean equals(Object o) {
4297                if (o instanceof Candidate) {
4298                    Symbol s1 = this.sym;
4299                    Symbol s2 = ((Candidate)o).sym;
4300                    if  ((s1 != s2 &&
4301                            (s1.overrides(s2, s1.owner.type.tsym, types, false) ||
4302                            (s2.overrides(s1, s2.owner.type.tsym, types, false)))) ||
4303                            ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner))
4304                        return true;
4305                }
4306                return false;
4307            }
4308
4309            boolean isApplicable() {
4310                return mtype != null;
4311            }
4312        }
4313
4314        DeferredAttr.AttrMode attrMode() {
4315            return attrMode;
4316        }
4317
4318        boolean internal() {
4319            return internalResolution;
4320        }
4321    }
4322
4323    MethodResolutionContext currentResolutionContext = null;
4324}
4325