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