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