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