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