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