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