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