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