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