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