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