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