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