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