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