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