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