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