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