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