1 /*
   2  * Copyright (c) 1999, 2013, 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.Symbol.*;
  31 import com.sun.tools.javac.code.Type.*;
  32 import com.sun.tools.javac.comp.Attr.ResultInfo;
  33 import com.sun.tools.javac.comp.Check.CheckContext;
  34 import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
  35 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
  36 import com.sun.tools.javac.comp.DeferredAttr.DeferredType;
  37 import com.sun.tools.javac.comp.Infer.InferenceContext;
  38 import com.sun.tools.javac.comp.Infer.FreeTypeListener;
  39 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
  40 import com.sun.tools.javac.jvm.*;
  41 import com.sun.tools.javac.tree.*;
  42 import com.sun.tools.javac.tree.JCTree.*;
  43 import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
  44 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
  45 import com.sun.tools.javac.util.*;
  46 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
  47 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  48 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
  49 
  50 import java.util.Arrays;
  51 import java.util.Collection;
  52 import java.util.EnumMap;
  53 import java.util.EnumSet;
  54 import java.util.Iterator;
  55 import java.util.LinkedHashMap;
  56 import java.util.LinkedHashSet;
  57 import java.util.Map;
  58 
  59 import javax.lang.model.element.ElementVisitor;
  60 
  61 import static com.sun.tools.javac.code.Flags.*;
  62 import static com.sun.tools.javac.code.Flags.BLOCK;
  63 import static com.sun.tools.javac.code.Kinds.*;
  64 import static com.sun.tools.javac.code.Kinds.ERRONEOUS;
  65 import static com.sun.tools.javac.code.TypeTag.*;
  66 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
  67 import static com.sun.tools.javac.tree.JCTree.Tag.*;
  68 
  69 /** Helper class for name resolution, used mostly by the attribution phase.
  70  *
  71  *  <p><b>This is NOT part of any supported API.
  72  *  If you write code that depends on this, you do so at your own risk.
  73  *  This code and its internal interfaces are subject to change or
  74  *  deletion without notice.</b>
  75  */
  76 public class Resolve {
  77     protected static final Context.Key<Resolve> resolveKey =
  78         new Context.Key<Resolve>();
  79 
  80     Names names;
  81     Log log;
  82     Symtab syms;
  83     Attr attr;
  84     DeferredAttr deferredAttr;
  85     Check chk;
  86     Infer infer;
  87     ClassReader reader;
  88     TreeInfo treeinfo;
  89     Types types;
  90     JCDiagnostic.Factory diags;
  91     public final boolean boxingEnabled; // = source.allowBoxing();
  92     public final boolean varargsEnabled; // = source.allowVarargs();
  93     public final boolean allowMethodHandles;
  94     public final boolean allowDefaultMethods;
  95     public final boolean allowStructuralMostSpecific;
  96     private final boolean debugResolve;
  97     final EnumSet<VerboseResolutionMode> verboseResolutionMode;
  98 
  99     Scope polymorphicSignatureScope;
 100 
 101     protected Resolve(Context context) {
 102         context.put(resolveKey, this);
 103         syms = Symtab.instance(context);
 104 
 105         varNotFound = new
 106             SymbolNotFoundError(ABSENT_VAR);
 107         methodNotFound = new
 108             SymbolNotFoundError(ABSENT_MTH);
 109         typeNotFound = new
 110             SymbolNotFoundError(ABSENT_TYP);
 111 
 112         names = Names.instance(context);
 113         log = Log.instance(context);
 114         attr = Attr.instance(context);
 115         deferredAttr = DeferredAttr.instance(context);
 116         chk = Check.instance(context);
 117         infer = Infer.instance(context);
 118         reader = ClassReader.instance(context);
 119         treeinfo = TreeInfo.instance(context);
 120         types = Types.instance(context);
 121         diags = JCDiagnostic.Factory.instance(context);
 122         Source source = Source.instance(context);
 123         boxingEnabled = source.allowBoxing();
 124         varargsEnabled = source.allowVarargs();
 125         Options options = Options.instance(context);
 126         debugResolve = options.isSet("debugresolve");
 127         verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
 128         Target target = Target.instance(context);
 129         allowMethodHandles = target.hasMethodHandles();
 130         allowDefaultMethods = source.allowDefaultMethods();
 131         allowStructuralMostSpecific = source.allowStructuralMostSpecific();
 132         polymorphicSignatureScope = new Scope(syms.noSymbol);
 133 
 134         inapplicableMethodException = new InapplicableMethodException(diags);
 135     }
 136 
 137     /** error symbols, which are returned when resolution fails
 138      */
 139     private final SymbolNotFoundError varNotFound;
 140     private final SymbolNotFoundError methodNotFound;
 141     private final SymbolNotFoundError typeNotFound;
 142 
 143     public static Resolve instance(Context context) {
 144         Resolve instance = context.get(resolveKey);
 145         if (instance == null)
 146             instance = new Resolve(context);
 147         return instance;
 148     }
 149 
 150     // <editor-fold defaultstate="collapsed" desc="Verbose resolution diagnostics support">
 151     enum VerboseResolutionMode {
 152         SUCCESS("success"),
 153         FAILURE("failure"),
 154         APPLICABLE("applicable"),
 155         INAPPLICABLE("inapplicable"),
 156         DEFERRED_INST("deferred-inference"),
 157         PREDEF("predef"),
 158         OBJECT_INIT("object-init"),
 159         INTERNAL("internal");
 160 
 161         final String opt;
 162 
 163         private VerboseResolutionMode(String opt) {
 164             this.opt = opt;
 165         }
 166 
 167         static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) {
 168             String s = opts.get("verboseResolution");
 169             EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class);
 170             if (s == null) return res;
 171             if (s.contains("all")) {
 172                 res = EnumSet.allOf(VerboseResolutionMode.class);
 173             }
 174             Collection<String> args = Arrays.asList(s.split(","));
 175             for (VerboseResolutionMode mode : values()) {
 176                 if (args.contains(mode.opt)) {
 177                     res.add(mode);
 178                 } else if (args.contains("-" + mode.opt)) {
 179                     res.remove(mode);
 180                 }
 181             }
 182             return res;
 183         }
 184     }
 185 
 186     void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site,
 187             List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) {
 188         boolean success = bestSoFar.kind < ERRONEOUS;
 189 
 190         if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) {
 191             return;
 192         } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) {
 193             return;
 194         }
 195 
 196         if (bestSoFar.name == names.init &&
 197                 bestSoFar.owner == syms.objectType.tsym &&
 198                 !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) {
 199             return; //skip diags for Object constructor resolution
 200         } else if (site == syms.predefClass.type &&
 201                 !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) {
 202             return; //skip spurious diags for predef symbols (i.e. operators)
 203         } else if (currentResolutionContext.internalResolution &&
 204                 !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) {
 205             return;
 206         }
 207 
 208         int pos = 0;
 209         int mostSpecificPos = -1;
 210         ListBuffer<JCDiagnostic> subDiags = ListBuffer.lb();
 211         for (Candidate c : currentResolutionContext.candidates) {
 212             if (currentResolutionContext.step != c.step ||
 213                     (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) ||
 214                     (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) {
 215                 continue;
 216             } else {
 217                 subDiags.append(c.isApplicable() ?
 218                         getVerboseApplicableCandidateDiag(pos, c.sym, c.mtype) :
 219                         getVerboseInapplicableCandidateDiag(pos, c.sym, c.details));
 220                 if (c.sym == bestSoFar)
 221                     mostSpecificPos = pos;
 222                 pos++;
 223             }
 224         }
 225         String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1";
 226         List<Type> argtypes2 = Type.map(argtypes,
 227                     deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, bestSoFar, currentResolutionContext.step));
 228         JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name,
 229                 site.tsym, mostSpecificPos, currentResolutionContext.step,
 230                 methodArguments(argtypes2),
 231                 methodArguments(typeargtypes));
 232         JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList());
 233         log.report(d);
 234     }
 235 
 236     JCDiagnostic getVerboseApplicableCandidateDiag(int pos, Symbol sym, Type inst) {
 237         JCDiagnostic subDiag = null;
 238         if (sym.type.hasTag(FORALL)) {
 239             subDiag = diags.fragment("partial.inst.sig", inst);
 240         }
 241 
 242         String key = subDiag == null ?
 243                 "applicable.method.found" :
 244                 "applicable.method.found.1";
 245 
 246         return diags.fragment(key, pos, sym, subDiag);
 247     }
 248 
 249     JCDiagnostic getVerboseInapplicableCandidateDiag(int pos, Symbol sym, JCDiagnostic subDiag) {
 250         return diags.fragment("not.applicable.method.found", pos, sym, subDiag);
 251     }
 252     // </editor-fold>
 253 
 254 /* ************************************************************************
 255  * Identifier resolution
 256  *************************************************************************/
 257 
 258     /** An environment is "static" if its static level is greater than
 259      *  the one of its outer environment
 260      */
 261     protected static boolean isStatic(Env<AttrContext> env) {
 262         return env.info.staticLevel > env.outer.info.staticLevel;
 263     }
 264 
 265     /** An environment is an "initializer" if it is a constructor or
 266      *  an instance initializer.
 267      */
 268     static boolean isInitializer(Env<AttrContext> env) {
 269         Symbol owner = env.info.scope.owner;
 270         return owner.isConstructor() ||
 271             owner.owner.kind == TYP &&
 272             (owner.kind == VAR ||
 273              owner.kind == MTH && (owner.flags() & BLOCK) != 0) &&
 274             (owner.flags() & STATIC) == 0;
 275     }
 276 
 277     /** Is class accessible in given evironment?
 278      *  @param env    The current environment.
 279      *  @param c      The class whose accessibility is checked.
 280      */
 281     public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) {
 282         return isAccessible(env, c, false);
 283     }
 284 
 285     public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) {
 286         boolean isAccessible = false;
 287         switch ((short)(c.flags() & AccessFlags)) {
 288             case PRIVATE:
 289                 isAccessible =
 290                     env.enclClass.sym.outermostClass() ==
 291                     c.owner.outermostClass();
 292                 break;
 293             case 0:
 294                 isAccessible =
 295                     env.toplevel.packge == c.owner // fast special case
 296                     ||
 297                     env.toplevel.packge == c.packge()
 298                     ||
 299                     // Hack: this case is added since synthesized default constructors
 300                     // of anonymous classes should be allowed to access
 301                     // classes which would be inaccessible otherwise.
 302                     env.enclMethod != null &&
 303                     (env.enclMethod.mods.flags & ANONCONSTR) != 0;
 304                 break;
 305             default: // error recovery
 306             case PUBLIC:
 307                 isAccessible = true;
 308                 break;
 309             case PROTECTED:
 310                 isAccessible =
 311                     env.toplevel.packge == c.owner // fast special case
 312                     ||
 313                     env.toplevel.packge == c.packge()
 314                     ||
 315                     isInnerSubClass(env.enclClass.sym, c.owner);
 316                 break;
 317         }
 318         return (checkInner == false || c.type.getEnclosingType() == Type.noType) ?
 319             isAccessible :
 320             isAccessible && isAccessible(env, c.type.getEnclosingType(), checkInner);
 321     }
 322     //where
 323         /** Is given class a subclass of given base class, or an inner class
 324          *  of a subclass?
 325          *  Return null if no such class exists.
 326          *  @param c     The class which is the subclass or is contained in it.
 327          *  @param base  The base class
 328          */
 329         private boolean isInnerSubClass(ClassSymbol c, Symbol base) {
 330             while (c != null && !c.isSubClass(base, types)) {
 331                 c = c.owner.enclClass();
 332             }
 333             return c != null;
 334         }
 335 
 336     boolean isAccessible(Env<AttrContext> env, Type t) {
 337         return isAccessible(env, t, false);
 338     }
 339 
 340     boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) {
 341         return (t.hasTag(ARRAY))
 342             ? isAccessible(env, types.elemtype(t))
 343             : isAccessible(env, t.tsym, checkInner);
 344     }
 345 
 346     /** Is symbol accessible as a member of given type in given evironment?
 347      *  @param env    The current environment.
 348      *  @param site   The type of which the tested symbol is regarded
 349      *                as a member.
 350      *  @param sym    The symbol.
 351      */
 352     public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) {
 353         return isAccessible(env, site, sym, false);
 354     }
 355     public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) {
 356         if (sym.name == names.init && sym.owner != site.tsym) return false;
 357         switch ((short)(sym.flags() & AccessFlags)) {
 358         case PRIVATE:
 359             return
 360                 (env.enclClass.sym == sym.owner // fast special case
 361                  ||
 362                  env.enclClass.sym.outermostClass() ==
 363                  sym.owner.outermostClass())
 364                 &&
 365                 sym.isInheritedIn(site.tsym, types);
 366         case 0:
 367             return
 368                 (env.toplevel.packge == sym.owner.owner // fast special case
 369                  ||
 370                  env.toplevel.packge == sym.packge())
 371                 &&
 372                 isAccessible(env, site, checkInner)
 373                 &&
 374                 sym.isInheritedIn(site.tsym, types)
 375                 &&
 376                 notOverriddenIn(site, sym);
 377         case PROTECTED:
 378             return
 379                 (env.toplevel.packge == sym.owner.owner // fast special case
 380                  ||
 381                  env.toplevel.packge == sym.packge()
 382                  ||
 383                  isProtectedAccessible(sym, env.enclClass.sym, site)
 384                  ||
 385                  // OK to select instance method or field from 'super' or type name
 386                  // (but type names should be disallowed elsewhere!)
 387                  env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP)
 388                 &&
 389                 isAccessible(env, site, checkInner)
 390                 &&
 391                 notOverriddenIn(site, sym);
 392         default: // this case includes erroneous combinations as well
 393             return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym);
 394         }
 395     }
 396     //where
 397     /* `sym' is accessible only if not overridden by
 398      * another symbol which is a member of `site'
 399      * (because, if it is overridden, `sym' is not strictly
 400      * speaking a member of `site'). A polymorphic signature method
 401      * cannot be overridden (e.g. MH.invokeExact(Object[])).
 402      */
 403     private boolean notOverriddenIn(Type site, Symbol sym) {
 404         if (sym.kind != MTH || sym.isConstructor() || sym.isStatic())
 405             return true;
 406         else {
 407             Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true);
 408             return (s2 == null || s2 == sym || sym.owner == s2.owner ||
 409                     !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
 410         }
 411     }
 412     //where
 413         /** Is given protected symbol accessible if it is selected from given site
 414          *  and the selection takes place in given class?
 415          *  @param sym     The symbol with protected access
 416          *  @param c       The class where the access takes place
 417          *  @site          The type of the qualifier
 418          */
 419         private
 420         boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) {
 421             while (c != null &&
 422                    !(c.isSubClass(sym.owner, types) &&
 423                      (c.flags() & INTERFACE) == 0 &&
 424                      // In JLS 2e 6.6.2.1, the subclass restriction applies
 425                      // only to instance fields and methods -- types are excluded
 426                      // regardless of whether they are declared 'static' or not.
 427                      ((sym.flags() & STATIC) != 0 || sym.kind == TYP || site.tsym.isSubClass(c, types))))
 428                 c = c.owner.enclClass();
 429             return c != null;
 430         }
 431 
 432     /**
 433      * Performs a recursive scan of a type looking for accessibility problems
 434      * from current attribution environment
 435      */
 436     void checkAccessibleType(Env<AttrContext> env, Type t) {
 437         accessibilityChecker.visit(t, env);
 438     }
 439 
 440     /**
 441      * Accessibility type-visitor
 442      */
 443     Types.SimpleVisitor<Void, Env<AttrContext>> accessibilityChecker =
 444             new Types.SimpleVisitor<Void, Env<AttrContext>>() {
 445 
 446         void visit(List<Type> ts, Env<AttrContext> env) {
 447             for (Type t : ts) {
 448                 visit(t, env);
 449             }
 450         }
 451 
 452         public Void visitType(Type t, Env<AttrContext> env) {
 453             return null;
 454         }
 455 
 456         @Override
 457         public Void visitArrayType(ArrayType t, Env<AttrContext> env) {
 458             visit(t.elemtype, env);
 459             return null;
 460         }
 461 
 462         @Override
 463         public Void visitClassType(ClassType t, Env<AttrContext> env) {
 464             visit(t.getTypeArguments(), env);
 465             if (!isAccessible(env, t, true)) {
 466                 accessBase(new AccessError(t.tsym), env.tree.pos(), env.enclClass.sym, t, t.tsym.name, true);
 467             }
 468             return null;
 469         }
 470 
 471         @Override
 472         public Void visitWildcardType(WildcardType t, Env<AttrContext> env) {
 473             visit(t.type, env);
 474             return null;
 475         }
 476 
 477         @Override
 478         public Void visitMethodType(MethodType t, Env<AttrContext> env) {
 479             visit(t.getParameterTypes(), env);
 480             visit(t.getReturnType(), env);
 481             visit(t.getThrownTypes(), env);
 482             return null;
 483         }
 484     };
 485 
 486     /** Try to instantiate the type of a method so that it fits
 487      *  given type arguments and argument types. If succesful, return
 488      *  the method's instantiated type, else return null.
 489      *  The instantiation will take into account an additional leading
 490      *  formal parameter if the method is an instance method seen as a member
 491      *  of un underdetermined site In this case, we treat site as an additional
 492      *  parameter and the parameters of the class containing the method as
 493      *  additional type variables that get instantiated.
 494      *
 495      *  @param env         The current environment
 496      *  @param site        The type of which the method is a member.
 497      *  @param m           The method symbol.
 498      *  @param argtypes    The invocation's given value arguments.
 499      *  @param typeargtypes    The invocation's given type arguments.
 500      *  @param allowBoxing Allow boxing conversions of arguments.
 501      *  @param useVarargs Box trailing arguments into an array for varargs.
 502      */
 503     Type rawInstantiate(Env<AttrContext> env,
 504                         Type site,
 505                         Symbol m,
 506                         ResultInfo resultInfo,
 507                         List<Type> argtypes,
 508                         List<Type> typeargtypes,
 509                         boolean allowBoxing,
 510                         boolean useVarargs,
 511                         Warner warn) throws Infer.InferenceException {
 512 
 513         Type mt = types.memberType(site, m);
 514         // tvars is the list of formal type variables for which type arguments
 515         // need to inferred.
 516         List<Type> tvars = List.nil();
 517         if (typeargtypes == null) typeargtypes = List.nil();
 518         if (!mt.hasTag(FORALL) && typeargtypes.nonEmpty()) {
 519             // This is not a polymorphic method, but typeargs are supplied
 520             // which is fine, see JLS 15.12.2.1
 521         } else if (mt.hasTag(FORALL) && typeargtypes.nonEmpty()) {
 522             ForAll pmt = (ForAll) mt;
 523             if (typeargtypes.length() != pmt.tvars.length())
 524                 throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
 525             // Check type arguments are within bounds
 526             List<Type> formals = pmt.tvars;
 527             List<Type> actuals = typeargtypes;
 528             while (formals.nonEmpty() && actuals.nonEmpty()) {
 529                 List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head),
 530                                                 pmt.tvars, typeargtypes);
 531                 for (; bounds.nonEmpty(); bounds = bounds.tail)
 532                     if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn))
 533                         throw inapplicableMethodException.setMessage("explicit.param.do.not.conform.to.bounds",actuals.head, bounds);
 534                 formals = formals.tail;
 535                 actuals = actuals.tail;
 536             }
 537             mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes);
 538         } else if (mt.hasTag(FORALL)) {
 539             ForAll pmt = (ForAll) mt;
 540             List<Type> tvars1 = types.newInstances(pmt.tvars);
 541             tvars = tvars.appendList(tvars1);
 542             mt = types.subst(pmt.qtype, pmt.tvars, tvars1);
 543         }
 544 
 545         // find out whether we need to go the slow route via infer
 546         boolean instNeeded = tvars.tail != null; /*inlined: tvars.nonEmpty()*/
 547         for (List<Type> l = argtypes;
 548              l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
 549              l = l.tail) {
 550             if (l.head.hasTag(FORALL)) instNeeded = true;
 551         }
 552 
 553         if (instNeeded)
 554             return infer.instantiateMethod(env,
 555                                     tvars,
 556                                     (MethodType)mt,
 557                                     resultInfo,
 558                                     m,
 559                                     argtypes,
 560                                     allowBoxing,
 561                                     useVarargs,
 562                                     currentResolutionContext,
 563                                     warn);
 564 
 565         currentResolutionContext.methodCheck.argumentsAcceptable(env, currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn),
 566                                 argtypes, mt.getParameterTypes(), warn);
 567         return mt;
 568     }
 569 
 570     Type checkMethod(Env<AttrContext> env,
 571                      Type site,
 572                      Symbol m,
 573                      ResultInfo resultInfo,
 574                      List<Type> argtypes,
 575                      List<Type> typeargtypes,
 576                      Warner warn) {
 577         MethodResolutionContext prevContext = currentResolutionContext;
 578         try {
 579             currentResolutionContext = new MethodResolutionContext();
 580             currentResolutionContext.attrMode = DeferredAttr.AttrMode.CHECK;
 581             MethodResolutionPhase step = currentResolutionContext.step = env.info.pendingResolutionPhase;
 582             return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
 583                     step.isBoxingRequired(), step.isVarargsRequired(), warn);
 584         }
 585         finally {
 586             currentResolutionContext = prevContext;
 587         }
 588     }
 589 
 590     /** Same but returns null instead throwing a NoInstanceException
 591      */
 592     Type instantiate(Env<AttrContext> env,
 593                      Type site,
 594                      Symbol m,
 595                      ResultInfo resultInfo,
 596                      List<Type> argtypes,
 597                      List<Type> typeargtypes,
 598                      boolean allowBoxing,
 599                      boolean useVarargs,
 600                      Warner warn) {
 601         try {
 602             return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
 603                                   allowBoxing, useVarargs, warn);
 604         } catch (InapplicableMethodException ex) {
 605             return null;
 606         }
 607     }
 608 
 609     /**
 610      * This interface defines an entry point that should be used to perform a
 611      * method check. A method check usually consist in determining as to whether
 612      * a set of types (actuals) is compatible with another set of types (formals).
 613      * Since the notion of compatibility can vary depending on the circumstances,
 614      * this interfaces allows to easily add new pluggable method check routines.
 615      */
 616     interface MethodCheck {
 617         /**
 618          * Main method check routine. A method check usually consist in determining
 619          * as to whether a set of types (actuals) is compatible with another set of
 620          * types (formals). If an incompatibility is found, an unchecked exception
 621          * is assumed to be thrown.
 622          */
 623         void argumentsAcceptable(Env<AttrContext> env,
 624                                 DeferredAttrContext deferredAttrContext,
 625                                 List<Type> argtypes,
 626                                 List<Type> formals,
 627                                 Warner warn);
 628 
 629         /**
 630          * Retrieve the method check object that will be used during a
 631          * most specific check.
 632          */
 633         MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict);
 634     }
 635 
 636     /**
 637      * Helper enum defining all method check diagnostics (used by resolveMethodCheck).
 638      */
 639     enum MethodCheckDiag {
 640         /**
 641          * Actuals and formals differs in length.
 642          */
 643         ARITY_MISMATCH("arg.length.mismatch", "infer.arg.length.mismatch"),
 644         /**
 645          * An actual is incompatible with a formal.
 646          */
 647         ARG_MISMATCH("no.conforming.assignment.exists", "infer.no.conforming.assignment.exists"),
 648         /**
 649          * An actual is incompatible with the varargs element type.
 650          */
 651         VARARG_MISMATCH("varargs.argument.mismatch", "infer.varargs.argument.mismatch"),
 652         /**
 653          * The varargs element type is inaccessible.
 654          */
 655         INACCESSIBLE_VARARGS("inaccessible.varargs.type", "inaccessible.varargs.type");
 656 
 657         final String basicKey;
 658         final String inferKey;
 659 
 660         MethodCheckDiag(String basicKey, String inferKey) {
 661             this.basicKey = basicKey;
 662             this.inferKey = inferKey;
 663         }
 664     }
 665 
 666     /**
 667      * Dummy method check object. All methods are deemed applicable, regardless
 668      * of their formal parameter types.
 669      */
 670     MethodCheck nilMethodCheck = new MethodCheck() {
 671         public void argumentsAcceptable(Env<AttrContext> env, DeferredAttrContext deferredAttrContext, List<Type> argtypes, List<Type> formals, Warner warn) {
 672             //do nothing - method always applicable regardless of actuals
 673         }
 674 
 675         public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
 676             return this;
 677         }
 678     };
 679 
 680     /**
 681      * Base class for 'real' method checks. The class defines the logic for
 682      * iterating through formals and actuals and provides and entry point
 683      * that can be used by subclasses in order to define the actual check logic.
 684      */
 685     abstract class AbstractMethodCheck implements MethodCheck {
 686         @Override
 687         public void argumentsAcceptable(final Env<AttrContext> env,
 688                                     DeferredAttrContext deferredAttrContext,
 689                                     List<Type> argtypes,
 690                                     List<Type> formals,
 691                                     Warner warn) {
 692             //should we expand formals?
 693             boolean useVarargs = deferredAttrContext.phase.isVarargsRequired();
 694 
 695             //inference context used during this method check
 696             InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
 697 
 698             Type varargsFormal = useVarargs ? formals.last() : null;
 699 
 700             if (varargsFormal == null &&
 701                     argtypes.size() != formals.size()) {
 702                 reportMC(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
 703             }
 704 
 705             while (argtypes.nonEmpty() && formals.head != varargsFormal) {
 706                 checkArg(false, argtypes.head, formals.head, deferredAttrContext, warn);
 707                 argtypes = argtypes.tail;
 708                 formals = formals.tail;
 709             }
 710 
 711             if (formals.head != varargsFormal) {
 712                 reportMC(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
 713             }
 714 
 715             if (useVarargs) {
 716                 //note: if applicability check is triggered by most specific test,
 717                 //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
 718                 final Type elt = types.elemtype(varargsFormal);
 719                 while (argtypes.nonEmpty()) {
 720                     checkArg(true, argtypes.head, elt, deferredAttrContext, warn);
 721                     argtypes = argtypes.tail;
 722                 }
 723             }
 724         }
 725 
 726         /**
 727          * Does the actual argument conforms to the corresponding formal?
 728          */
 729         abstract void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn);
 730 
 731         protected void reportMC(MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) {
 732             boolean inferDiag = inferenceContext != infer.emptyContext;
 733             InapplicableMethodException ex = inferDiag ?
 734                     infer.inferenceException : inapplicableMethodException;
 735             if (inferDiag && (!diag.inferKey.equals(diag.basicKey))) {
 736                 Object[] args2 = new Object[args.length + 1];
 737                 System.arraycopy(args, 0, args2, 1, args.length);
 738                 args2[0] = inferenceContext.inferenceVars();
 739                 args = args2;
 740             }
 741             throw ex.setMessage(inferDiag ? diag.inferKey : diag.basicKey, args);
 742         }
 743 
 744         public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
 745             return nilMethodCheck;
 746         }
 747     }
 748 
 749     /**
 750      * Arity-based method check. A method is applicable if the number of actuals
 751      * supplied conforms to the method signature.
 752      */
 753     MethodCheck arityMethodCheck = new AbstractMethodCheck() {
 754         @Override
 755         void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
 756             //do nothing - actual always compatible to formals
 757         }
 758     };
 759 
 760     /**
 761      * Main method applicability routine. Given a list of actual types A,
 762      * a list of formal types F, determines whether the types in A are
 763      * compatible (by method invocation conversion) with the types in F.
 764      *
 765      * Since this routine is shared between overload resolution and method
 766      * type-inference, a (possibly empty) inference context is used to convert
 767      * formal types to the corresponding 'undet' form ahead of a compatibility
 768      * check so that constraints can be propagated and collected.
 769      *
 770      * Moreover, if one or more types in A is a deferred type, this routine uses
 771      * DeferredAttr in order to perform deferred attribution. If one or more actual
 772      * deferred types are stuck, they are placed in a queue and revisited later
 773      * after the remainder of the arguments have been seen. If this is not sufficient
 774      * to 'unstuck' the argument, a cyclic inference error is called out.
 775      *
 776      * A method check handler (see above) is used in order to report errors.
 777      */
 778     MethodCheck resolveMethodCheck = new AbstractMethodCheck() {
 779 
 780         @Override
 781         void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
 782             ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn);
 783             mresult.check(null, actual);
 784         }
 785 
 786         @Override
 787         public void argumentsAcceptable(final Env<AttrContext> env,
 788                                     DeferredAttrContext deferredAttrContext,
 789                                     List<Type> argtypes,
 790                                     List<Type> formals,
 791                                     Warner warn) {
 792             super.argumentsAcceptable(env, deferredAttrContext, argtypes, formals, warn);
 793             //should we expand formals?
 794             if (deferredAttrContext.phase.isVarargsRequired()) {
 795                 //check varargs element type accessibility
 796                 varargsAccessible(env, types.elemtype(formals.last()),
 797                         deferredAttrContext.inferenceContext);
 798             }
 799         }
 800 
 801         private void varargsAccessible(final Env<AttrContext> env, final Type t, final InferenceContext inferenceContext) {
 802             if (inferenceContext.free(t)) {
 803                 inferenceContext.addFreeTypeListener(List.of(t), new FreeTypeListener() {
 804                     @Override
 805                     public void typesInferred(InferenceContext inferenceContext) {
 806                         varargsAccessible(env, inferenceContext.asInstType(t), inferenceContext);
 807                     }
 808                 });
 809             } else {
 810                 if (!isAccessible(env, t)) {
 811                     Symbol location = env.enclClass.sym;
 812                     reportMC(MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location);
 813                 }
 814             }
 815         }
 816 
 817         private ResultInfo methodCheckResult(final boolean varargsCheck, Type to,
 818                 final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) {
 819             CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) {
 820                 MethodCheckDiag methodDiag = varargsCheck ?
 821                                  MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH;
 822 
 823                 @Override
 824                 public void report(DiagnosticPosition pos, JCDiagnostic details) {
 825                     reportMC(methodDiag, deferredAttrContext.inferenceContext, details);
 826                 }
 827             };
 828             return new MethodResultInfo(to, checkContext);
 829         }
 830 
 831         @Override
 832         public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
 833             return new MostSpecificCheck(strict, actuals);
 834         }
 835     };
 836 
 837     /**
 838      * Check context to be used during method applicability checks. A method check
 839      * context might contain inference variables.
 840      */
 841     abstract class MethodCheckContext implements CheckContext {
 842 
 843         boolean strict;
 844         DeferredAttrContext deferredAttrContext;
 845         Warner rsWarner;
 846 
 847         public MethodCheckContext(boolean strict, DeferredAttrContext deferredAttrContext, Warner rsWarner) {
 848            this.strict = strict;
 849            this.deferredAttrContext = deferredAttrContext;
 850            this.rsWarner = rsWarner;
 851         }
 852 
 853         public boolean compatible(Type found, Type req, Warner warn) {
 854             return strict ?
 855                     types.isSubtypeUnchecked(found, deferredAttrContext.inferenceContext.asFree(req), warn) :
 856                     types.isConvertible(found, deferredAttrContext.inferenceContext.asFree(req), warn);
 857         }
 858 
 859         public void report(DiagnosticPosition pos, JCDiagnostic details) {
 860             throw inapplicableMethodException.setMessage(details);
 861         }
 862 
 863         public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
 864             return rsWarner;
 865         }
 866 
 867         public InferenceContext inferenceContext() {
 868             return deferredAttrContext.inferenceContext;
 869         }
 870 
 871         public DeferredAttrContext deferredAttrContext() {
 872             return deferredAttrContext;
 873         }
 874     }
 875 
 876     /**
 877      * ResultInfo class to be used during method applicability checks. Check
 878      * for deferred types goes through special path.
 879      */
 880     class MethodResultInfo extends ResultInfo {
 881 
 882         public MethodResultInfo(Type pt, CheckContext checkContext) {
 883             attr.super(VAL, pt, checkContext);
 884         }
 885 
 886         @Override
 887         protected Type check(DiagnosticPosition pos, Type found) {
 888             if (found.hasTag(DEFERRED)) {
 889                 DeferredType dt = (DeferredType)found;
 890                 return dt.check(this);
 891             } else {
 892                 return super.check(pos, chk.checkNonVoid(pos, types.capture(types.upperBound(found.baseType()))));
 893             }
 894         }
 895 
 896         @Override
 897         protected MethodResultInfo dup(Type newPt) {
 898             return new MethodResultInfo(newPt, checkContext);
 899         }
 900 
 901         @Override
 902         protected ResultInfo dup(CheckContext newContext) {
 903             return new MethodResultInfo(pt, newContext);
 904         }
 905     }
 906 
 907     /**
 908      * Most specific method applicability routine. Given a list of actual types A,
 909      * a list of formal types F1, and a list of formal types F2, the routine determines
 910      * as to whether the types in F1 can be considered more specific than those in F2 w.r.t.
 911      * argument types A.
 912      */
 913     class MostSpecificCheck implements MethodCheck {
 914 
 915         boolean strict;
 916         List<Type> actuals;
 917 
 918         MostSpecificCheck(boolean strict, List<Type> actuals) {
 919             this.strict = strict;
 920             this.actuals = actuals;
 921         }
 922 
 923         @Override
 924         public void argumentsAcceptable(final Env<AttrContext> env,
 925                                     DeferredAttrContext deferredAttrContext,
 926                                     List<Type> formals1,
 927                                     List<Type> formals2,
 928                                     Warner warn) {
 929             formals2 = adjustArgs(formals2, deferredAttrContext.msym, formals1.length(), deferredAttrContext.phase.isVarargsRequired());
 930             while (formals2.nonEmpty()) {
 931                 ResultInfo mresult = methodCheckResult(formals2.head, deferredAttrContext, warn, actuals.head);
 932                 mresult.check(null, formals1.head);
 933                 formals1 = formals1.tail;
 934                 formals2 = formals2.tail;
 935                 actuals = actuals.isEmpty() ? actuals : actuals.tail;
 936             }
 937         }
 938 
 939        /**
 940         * Create a method check context to be used during the most specific applicability check
 941         */
 942         ResultInfo methodCheckResult(Type to, DeferredAttr.DeferredAttrContext deferredAttrContext,
 943                Warner rsWarner, Type actual) {
 944            return attr.new ResultInfo(Kinds.VAL, to,
 945                    new MostSpecificCheckContext(strict, deferredAttrContext, rsWarner, actual));
 946         }
 947 
 948         /**
 949          * Subclass of method check context class that implements most specific
 950          * method conversion. If the actual type under analysis is a deferred type
 951          * a full blown structural analysis is carried out.
 952          */
 953         class MostSpecificCheckContext extends MethodCheckContext {
 954 
 955             Type actual;
 956 
 957             public MostSpecificCheckContext(boolean strict, DeferredAttrContext deferredAttrContext, Warner rsWarner, Type actual) {
 958                 super(strict, deferredAttrContext, rsWarner);
 959                 this.actual = actual;
 960             }
 961 
 962             public boolean compatible(Type found, Type req, Warner warn) {
 963                 if (!allowStructuralMostSpecific || actual == null) {
 964                     return super.compatible(found, req, warn);
 965                 } else {
 966                     switch (actual.getTag()) {
 967                         case DEFERRED:
 968                             DeferredType dt = (DeferredType) actual;
 969                             DeferredType.SpeculativeCache.Entry e = dt.speculativeCache.get(deferredAttrContext.msym, deferredAttrContext.phase);
 970                             return (e == null || e.speculativeTree == deferredAttr.stuckTree)
 971                                     ? false : mostSpecific(found, req, e.speculativeTree, warn);
 972                         default:
 973                             return standaloneMostSpecific(found, req, actual, warn);
 974                     }
 975                 }
 976             }
 977 
 978             private boolean mostSpecific(Type t, Type s, JCTree tree, Warner warn) {
 979                 MostSpecificChecker msc = new MostSpecificChecker(t, s, warn);
 980                 msc.scan(tree);
 981                 return msc.result;
 982             }
 983 
 984             boolean polyMostSpecific(Type t1, Type t2, Warner warn) {
 985                 return (!t1.isPrimitive() && t2.isPrimitive())
 986                         ? true : super.compatible(t1, t2, warn);
 987             }
 988 
 989             boolean standaloneMostSpecific(Type t1, Type t2, Type exprType, Warner warn) {
 990                 return (exprType.isPrimitive() == t1.isPrimitive()
 991                         && exprType.isPrimitive() != t2.isPrimitive())
 992                         ? true : super.compatible(t1, t2, warn);
 993             }
 994 
 995             /**
 996              * Structural checker for most specific.
 997              */
 998             class MostSpecificChecker extends DeferredAttr.PolyScanner {
 999 
1000                 final Type t;
1001                 final Type s;
1002                 final Warner warn;
1003                 boolean result;
1004 
1005                 MostSpecificChecker(Type t, Type s, Warner warn) {
1006                     this.t = t;
1007                     this.s = s;
1008                     this.warn = warn;
1009                     result = true;
1010                 }
1011 
1012                 @Override
1013                 void skip(JCTree tree) {
1014                     result &= standaloneMostSpecific(t, s, tree.type, warn);
1015                 }
1016 
1017                 @Override
1018                 public void visitConditional(JCConditional tree) {
1019                     if (tree.polyKind == PolyKind.STANDALONE) {
1020                         result &= standaloneMostSpecific(t, s, tree.type, warn);
1021                     } else {
1022                         super.visitConditional(tree);
1023                     }
1024                 }
1025 
1026                 @Override
1027                 public void visitApply(JCMethodInvocation tree) {
1028                     result &= (tree.polyKind == PolyKind.STANDALONE)
1029                             ? standaloneMostSpecific(t, s, tree.type, warn)
1030                             : polyMostSpecific(t, s, warn);
1031                 }
1032 
1033                 @Override
1034                 public void visitNewClass(JCNewClass tree) {
1035                     result &= (tree.polyKind == PolyKind.STANDALONE)
1036                             ? standaloneMostSpecific(t, s, tree.type, warn)
1037                             : polyMostSpecific(t, s, warn);
1038                 }
1039 
1040                 @Override
1041                 public void visitReference(JCMemberReference tree) {
1042                     if (types.isFunctionalInterface(t.tsym) &&
1043                             types.isFunctionalInterface(s.tsym) &&
1044                             types.asSuper(t, s.tsym) == null &&
1045                             types.asSuper(s, t.tsym) == null) {
1046                         Type desc_t = types.findDescriptorType(t);
1047                         Type desc_s = types.findDescriptorType(s);
1048                         if (types.isSameTypes(desc_t.getParameterTypes(), desc_s.getParameterTypes())) {
1049                             if (!desc_s.getReturnType().hasTag(VOID)) {
1050                                 //perform structural comparison
1051                                 Type ret_t = desc_t.getReturnType();
1052                                 Type ret_s = desc_s.getReturnType();
1053                                 result &= ((tree.refPolyKind == PolyKind.STANDALONE)
1054                                         ? standaloneMostSpecific(ret_t, ret_s, tree.sym.type.getReturnType(), warn)
1055                                         : polyMostSpecific(ret_t, ret_s, warn));
1056                             } else {
1057                                 return;
1058                             }
1059                         } else {
1060                             result &= false;
1061                         }
1062                     } else {
1063                         result &= MostSpecificCheckContext.super.compatible(t, s, warn);
1064                     }
1065                 }
1066 
1067                 @Override
1068                 public void visitLambda(JCLambda tree) {
1069                     if (types.isFunctionalInterface(t.tsym) &&
1070                             types.isFunctionalInterface(s.tsym) &&
1071                             types.asSuper(t, s.tsym) == null &&
1072                             types.asSuper(s, t.tsym) == null) {
1073                         Type desc_t = types.findDescriptorType(t);
1074                         Type desc_s = types.findDescriptorType(s);
1075                         if (tree.paramKind == JCLambda.ParameterKind.EXPLICIT
1076                                 || types.isSameTypes(desc_t.getParameterTypes(), desc_s.getParameterTypes())) {
1077                             if (!desc_s.getReturnType().hasTag(VOID)) {
1078                                 //perform structural comparison
1079                                 Type ret_t = desc_t.getReturnType();
1080                                 Type ret_s = desc_s.getReturnType();
1081                                 scanLambdaBody(tree, ret_t, ret_s);
1082                             } else {
1083                                 return;
1084                             }
1085                         } else {
1086                             result &= false;
1087                         }
1088                     } else {
1089                         result &= MostSpecificCheckContext.super.compatible(t, s, warn);
1090                     }
1091                 }
1092                 //where
1093 
1094                 void scanLambdaBody(JCLambda lambda, final Type t, final Type s) {
1095                     if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) {
1096                         result &= MostSpecificCheckContext.this.mostSpecific(t, s, lambda.body, warn);
1097                     } else {
1098                         DeferredAttr.LambdaReturnScanner lambdaScanner =
1099                                 new DeferredAttr.LambdaReturnScanner() {
1100                                     @Override
1101                                     public void visitReturn(JCReturn tree) {
1102                                         if (tree.expr != null) {
1103                                             result &= MostSpecificCheckContext.this.mostSpecific(t, s, tree.expr, warn);
1104                                         }
1105                                     }
1106                                 };
1107                         lambdaScanner.scan(lambda.body);
1108                     }
1109                 }
1110             }
1111         }
1112 
1113         public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
1114             Assert.error("Cannot get here!");
1115             return null;
1116         }
1117     }
1118 
1119     public static class InapplicableMethodException extends RuntimeException {
1120         private static final long serialVersionUID = 0;
1121 
1122         JCDiagnostic diagnostic;
1123         JCDiagnostic.Factory diags;
1124 
1125         InapplicableMethodException(JCDiagnostic.Factory diags) {
1126             this.diagnostic = null;
1127             this.diags = diags;
1128         }
1129         InapplicableMethodException setMessage() {
1130             return setMessage((JCDiagnostic)null);
1131         }
1132         InapplicableMethodException setMessage(String key) {
1133             return setMessage(key != null ? diags.fragment(key) : null);
1134         }
1135         InapplicableMethodException setMessage(String key, Object... args) {
1136             return setMessage(key != null ? diags.fragment(key, args) : null);
1137         }
1138         InapplicableMethodException setMessage(JCDiagnostic diag) {
1139             this.diagnostic = diag;
1140             return this;
1141         }
1142 
1143         public JCDiagnostic getDiagnostic() {
1144             return diagnostic;
1145         }
1146     }
1147     private final InapplicableMethodException inapplicableMethodException;
1148 
1149 /* ***************************************************************************
1150  *  Symbol lookup
1151  *  the following naming conventions for arguments are used
1152  *
1153  *       env      is the environment where the symbol was mentioned
1154  *       site     is the type of which the symbol is a member
1155  *       name     is the symbol's name
1156  *                if no arguments are given
1157  *       argtypes are the value arguments, if we search for a method
1158  *
1159  *  If no symbol was found, a ResolveError detailing the problem is returned.
1160  ****************************************************************************/
1161 
1162     /** Find field. Synthetic fields are always skipped.
1163      *  @param env     The current environment.
1164      *  @param site    The original type from where the selection takes place.
1165      *  @param name    The name of the field.
1166      *  @param c       The class to search for the field. This is always
1167      *                 a superclass or implemented interface of site's class.
1168      */
1169     Symbol findField(Env<AttrContext> env,
1170                      Type site,
1171                      Name name,
1172                      TypeSymbol c) {
1173         while (c.type.hasTag(TYPEVAR))
1174             c = c.type.getUpperBound().tsym;
1175         Symbol bestSoFar = varNotFound;
1176         Symbol sym;
1177         Scope.Entry e = c.members().lookup(name);
1178         while (e.scope != null) {
1179             if (e.sym.kind == VAR && (e.sym.flags_field & SYNTHETIC) == 0) {
1180                 return isAccessible(env, site, e.sym)
1181                     ? e.sym : new AccessError(env, site, e.sym);
1182             }
1183             e = e.next();
1184         }
1185         Type st = types.supertype(c.type);
1186         if (st != null && (st.hasTag(CLASS) || st.hasTag(TYPEVAR))) {
1187             sym = findField(env, site, name, st.tsym);
1188             if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1189         }
1190         for (List<Type> l = types.interfaces(c.type);
1191              bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
1192              l = l.tail) {
1193             sym = findField(env, site, name, l.head.tsym);
1194             if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&
1195                 sym.owner != bestSoFar.owner)
1196                 bestSoFar = new AmbiguityError(bestSoFar, sym);
1197             else if (sym.kind < bestSoFar.kind)
1198                 bestSoFar = sym;
1199         }
1200         return bestSoFar;
1201     }
1202 
1203     /** Resolve a field identifier, throw a fatal error if not found.
1204      *  @param pos       The position to use for error reporting.
1205      *  @param env       The environment current at the method invocation.
1206      *  @param site      The type of the qualifying expression, in which
1207      *                   identifier is searched.
1208      *  @param name      The identifier's name.
1209      */
1210     public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env,
1211                                           Type site, Name name) {
1212         Symbol sym = findField(env, site, name, site.tsym);
1213         if (sym.kind == VAR) return (VarSymbol)sym;
1214         else throw new FatalError(
1215                  diags.fragment("fatal.err.cant.locate.field",
1216                                 name));
1217     }
1218 
1219     /** Find unqualified variable or field with given name.
1220      *  Synthetic fields always skipped.
1221      *  @param env     The current environment.
1222      *  @param name    The name of the variable or field.
1223      */
1224     Symbol findVar(Env<AttrContext> env, Name name) {
1225         Symbol bestSoFar = varNotFound;
1226         Symbol sym;
1227         Env<AttrContext> env1 = env;
1228         boolean staticOnly = false;
1229         while (env1.outer != null) {
1230             if (isStatic(env1)) staticOnly = true;
1231             Scope.Entry e = env1.info.scope.lookup(name);
1232             while (e.scope != null &&
1233                    (e.sym.kind != VAR ||
1234                     (e.sym.flags_field & SYNTHETIC) != 0))
1235                 e = e.next();
1236             sym = (e.scope != null)
1237                 ? e.sym
1238                 : findField(
1239                     env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
1240             if (sym.exists()) {
1241                 if (staticOnly &&
1242                     sym.kind == VAR &&
1243                     sym.owner.kind == TYP &&
1244                     (sym.flags() & STATIC) == 0)
1245                     return new StaticError(sym);
1246                 else
1247                     return sym;
1248             } else if (sym.kind < bestSoFar.kind) {
1249                 bestSoFar = sym;
1250             }
1251 
1252             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
1253             env1 = env1.outer;
1254         }
1255 
1256         sym = findField(env, syms.predefClass.type, name, syms.predefClass);
1257         if (sym.exists())
1258             return sym;
1259         if (bestSoFar.exists())
1260             return bestSoFar;
1261 
1262         Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
1263         for (; e.scope != null; e = e.next()) {
1264             sym = e.sym;
1265             Type origin = e.getOrigin().owner.type;
1266             if (sym.kind == VAR) {
1267                 if (e.sym.owner.type != origin)
1268                     sym = sym.clone(e.getOrigin().owner);
1269                 return isAccessible(env, origin, sym)
1270                     ? sym : new AccessError(env, origin, sym);
1271             }
1272         }
1273 
1274         Symbol origin = null;
1275         e = env.toplevel.starImportScope.lookup(name);
1276         for (; e.scope != null; e = e.next()) {
1277             sym = e.sym;
1278             if (sym.kind != VAR)
1279                 continue;
1280             // invariant: sym.kind == VAR
1281             if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner)
1282                 return new AmbiguityError(bestSoFar, sym);
1283             else if (bestSoFar.kind >= VAR) {
1284                 origin = e.getOrigin().owner;
1285                 bestSoFar = isAccessible(env, origin.type, sym)
1286                     ? sym : new AccessError(env, origin.type, sym);
1287             }
1288         }
1289         if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type)
1290             return bestSoFar.clone(origin);
1291         else
1292             return bestSoFar;
1293     }
1294 
1295     Warner noteWarner = new Warner();
1296 
1297     /** Select the best method for a call site among two choices.
1298      *  @param env              The current environment.
1299      *  @param site             The original type from where the
1300      *                          selection takes place.
1301      *  @param argtypes         The invocation's value arguments,
1302      *  @param typeargtypes     The invocation's type arguments,
1303      *  @param sym              Proposed new best match.
1304      *  @param bestSoFar        Previously found best match.
1305      *  @param allowBoxing Allow boxing conversions of arguments.
1306      *  @param useVarargs Box trailing arguments into an array for varargs.
1307      */
1308     @SuppressWarnings("fallthrough")
1309     Symbol selectBest(Env<AttrContext> env,
1310                       Type site,
1311                       List<Type> argtypes,
1312                       List<Type> typeargtypes,
1313                       Symbol sym,
1314                       Symbol bestSoFar,
1315                       boolean allowBoxing,
1316                       boolean useVarargs,
1317                       boolean operator) {
1318         if (sym.kind == ERR ||
1319                 !sym.isInheritedIn(site.tsym, types)) {
1320             return bestSoFar;
1321         } else if (useVarargs && (sym.flags() & VARARGS) == 0) {
1322             return bestSoFar.kind >= ERRONEOUS ?
1323                     new BadVarargsMethod((ResolveError)bestSoFar) :
1324                     bestSoFar;
1325         }
1326         Assert.check(sym.kind < AMBIGUOUS);
1327         try {
1328             Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes,
1329                                allowBoxing, useVarargs, types.noWarnings);
1330             if (!operator)
1331                 currentResolutionContext.addApplicableCandidate(sym, mt);
1332         } catch (InapplicableMethodException ex) {
1333             if (!operator)
1334                 currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic());
1335             switch (bestSoFar.kind) {
1336                 case ABSENT_MTH:
1337                     return new InapplicableSymbolError(currentResolutionContext);
1338                 case WRONG_MTH:
1339                     if (operator) return bestSoFar;
1340                     bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
1341                 default:
1342                     return bestSoFar;
1343             }
1344         }
1345         if (!isAccessible(env, site, sym)) {
1346             return (bestSoFar.kind == ABSENT_MTH)
1347                 ? new AccessError(env, site, sym)
1348                 : bestSoFar;
1349         }
1350         return (bestSoFar.kind > AMBIGUOUS)
1351             ? sym
1352             : mostSpecific(argtypes, sym, bestSoFar, env, site,
1353                            allowBoxing && operator, useVarargs);
1354     }
1355 
1356     /* Return the most specific of the two methods for a call,
1357      *  given that both are accessible and applicable.
1358      *  @param m1               A new candidate for most specific.
1359      *  @param m2               The previous most specific candidate.
1360      *  @param env              The current environment.
1361      *  @param site             The original type from where the selection
1362      *                          takes place.
1363      *  @param allowBoxing Allow boxing conversions of arguments.
1364      *  @param useVarargs Box trailing arguments into an array for varargs.
1365      */
1366     Symbol mostSpecific(List<Type> argtypes, Symbol m1,
1367                         Symbol m2,
1368                         Env<AttrContext> env,
1369                         final Type site,
1370                         boolean allowBoxing,
1371                         boolean useVarargs) {
1372         switch (m2.kind) {
1373         case MTH:
1374             if (m1 == m2) return m1;
1375             boolean m1SignatureMoreSpecific =
1376                     signatureMoreSpecific(argtypes, env, site, m1, m2, allowBoxing, useVarargs);
1377             boolean m2SignatureMoreSpecific =
1378                     signatureMoreSpecific(argtypes, env, site, m2, m1, allowBoxing, useVarargs);
1379             if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) {
1380                 Type mt1 = types.memberType(site, m1);
1381                 Type mt2 = types.memberType(site, m2);
1382                 if (!types.overrideEquivalent(mt1, mt2))
1383                     return ambiguityError(m1, m2);
1384 
1385                 // same signature; select (a) the non-bridge method, or
1386                 // (b) the one that overrides the other, or (c) the concrete
1387                 // one, or (d) merge both abstract signatures
1388                 if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE))
1389                     return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
1390 
1391                 // if one overrides or hides the other, use it
1392                 TypeSymbol m1Owner = (TypeSymbol)m1.owner;
1393                 TypeSymbol m2Owner = (TypeSymbol)m2.owner;
1394                 if (types.asSuper(m1Owner.type, m2Owner) != null &&
1395                     ((m1.owner.flags_field & INTERFACE) == 0 ||
1396                      (m2.owner.flags_field & INTERFACE) != 0) &&
1397                     m1.overrides(m2, m1Owner, types, false))
1398                     return m1;
1399                 if (types.asSuper(m2Owner.type, m1Owner) != null &&
1400                     ((m2.owner.flags_field & INTERFACE) == 0 ||
1401                      (m1.owner.flags_field & INTERFACE) != 0) &&
1402                     m2.overrides(m1, m2Owner, types, false))
1403                     return m2;
1404                 boolean m1Abstract = (m1.flags() & ABSTRACT) != 0;
1405                 boolean m2Abstract = (m2.flags() & ABSTRACT) != 0;
1406                 if (m1Abstract && !m2Abstract) return m2;
1407                 if (m2Abstract && !m1Abstract) return m1;
1408                 // both abstract or both concrete
1409                 return ambiguityError(m1, m2);
1410             }
1411             if (m1SignatureMoreSpecific) return m1;
1412             if (m2SignatureMoreSpecific) return m2;
1413             return ambiguityError(m1, m2);
1414         case AMBIGUOUS:
1415             //check if m1 is more specific than all ambiguous methods in m2
1416             AmbiguityError e = (AmbiguityError)m2;
1417             for (Symbol s : e.ambiguousSyms) {
1418                 if (mostSpecific(argtypes, m1, s, env, site, allowBoxing, useVarargs) != m1) {
1419                     return e.addAmbiguousSymbol(m1);
1420                 }
1421             }
1422             return m1;
1423         default:
1424             throw new AssertionError();
1425         }
1426     }
1427     //where
1428     private boolean signatureMoreSpecific(List<Type> actuals, Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) {
1429         noteWarner.clear();
1430         int maxLength = Math.max(
1431                             Math.max(m1.type.getParameterTypes().length(), actuals.length()),
1432                             m2.type.getParameterTypes().length());
1433         MethodResolutionContext prevResolutionContext = currentResolutionContext;
1434         try {
1435             currentResolutionContext = new MethodResolutionContext();
1436             currentResolutionContext.step = prevResolutionContext.step;
1437             currentResolutionContext.methodCheck =
1438                     prevResolutionContext.methodCheck.mostSpecificCheck(actuals, !allowBoxing);
1439             Type mst = instantiate(env, site, m2, null,
1440                     adjustArgs(types.lowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null,
1441                     allowBoxing, useVarargs, noteWarner);
1442             return mst != null &&
1443                     !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
1444         } finally {
1445             currentResolutionContext = prevResolutionContext;
1446         }
1447     }
1448     private List<Type> adjustArgs(List<Type> args, Symbol msym, int length, boolean allowVarargs) {
1449         if ((msym.flags() & VARARGS) != 0 && allowVarargs) {
1450             Type varargsElem = types.elemtype(args.last());
1451             if (varargsElem == null) {
1452                 Assert.error("Bad varargs = " + args.last() + " " + msym);
1453             }
1454             List<Type> newArgs = args.reverse().tail.prepend(varargsElem).reverse();
1455             while (newArgs.length() < length) {
1456                 newArgs = newArgs.append(newArgs.last());
1457             }
1458             return newArgs;
1459         } else {
1460             return args;
1461         }
1462     }
1463     //where
1464     Type mostSpecificReturnType(Type mt1, Type mt2) {
1465         Type rt1 = mt1.getReturnType();
1466         Type rt2 = mt2.getReturnType();
1467 
1468         if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL)) {
1469             //if both are generic methods, adjust return type ahead of subtyping check
1470             rt1 = types.subst(rt1, mt1.getTypeArguments(), mt2.getTypeArguments());
1471         }
1472         //first use subtyping, then return type substitutability
1473         if (types.isSubtype(rt1, rt2)) {
1474             return mt1;
1475         } else if (types.isSubtype(rt2, rt1)) {
1476             return mt2;
1477         } else if (types.returnTypeSubstitutable(mt1, mt2)) {
1478             return mt1;
1479         } else if (types.returnTypeSubstitutable(mt2, mt1)) {
1480             return mt2;
1481         } else {
1482             return null;
1483         }
1484     }
1485     //where
1486     Symbol ambiguityError(Symbol m1, Symbol m2) {
1487         if (((m1.flags() | m2.flags()) & CLASH) != 0) {
1488             return (m1.flags() & CLASH) == 0 ? m1 : m2;
1489         } else {
1490             return new AmbiguityError(m1, m2);
1491         }
1492     }
1493 
1494     Symbol findMethodInScope(Env<AttrContext> env,
1495             Type site,
1496             Name name,
1497             List<Type> argtypes,
1498             List<Type> typeargtypes,
1499             Scope sc,
1500             Symbol bestSoFar,
1501             boolean allowBoxing,
1502             boolean useVarargs,
1503             boolean operator,
1504             boolean abstractok) {
1505         for (Symbol s : sc.getElementsByName(name, new LookupFilter(abstractok))) {
1506             bestSoFar = selectBest(env, site, argtypes, typeargtypes, s,
1507                     bestSoFar, allowBoxing, useVarargs, operator);
1508         }
1509         return bestSoFar;
1510     }
1511     //where
1512         class LookupFilter implements Filter<Symbol> {
1513 
1514             boolean abstractOk;
1515 
1516             LookupFilter(boolean abstractOk) {
1517                 this.abstractOk = abstractOk;
1518             }
1519 
1520             public boolean accepts(Symbol s) {
1521                 long flags = s.flags();
1522                 return s.kind == MTH &&
1523                         (flags & SYNTHETIC) == 0 &&
1524                         (abstractOk ||
1525                         (flags & DEFAULT) != 0 ||
1526                         (flags & ABSTRACT) == 0);
1527             }
1528         };
1529 
1530     /** Find best qualified method matching given name, type and value
1531      *  arguments.
1532      *  @param env       The current environment.
1533      *  @param site      The original type from where the selection
1534      *                   takes place.
1535      *  @param name      The method's name.
1536      *  @param argtypes  The method's value arguments.
1537      *  @param typeargtypes The method's type arguments
1538      *  @param allowBoxing Allow boxing conversions of arguments.
1539      *  @param useVarargs Box trailing arguments into an array for varargs.
1540      */
1541     Symbol findMethod(Env<AttrContext> env,
1542                       Type site,
1543                       Name name,
1544                       List<Type> argtypes,
1545                       List<Type> typeargtypes,
1546                       boolean allowBoxing,
1547                       boolean useVarargs,
1548                       boolean operator) {
1549         Symbol bestSoFar = methodNotFound;
1550         bestSoFar = findMethod(env,
1551                           site,
1552                           name,
1553                           argtypes,
1554                           typeargtypes,
1555                           site.tsym.type,
1556                           bestSoFar,
1557                           allowBoxing,
1558                           useVarargs,
1559                           operator);
1560         reportVerboseResolutionDiagnostic(env.tree.pos(), name, site, argtypes, typeargtypes, bestSoFar);
1561         return bestSoFar;
1562     }
1563     // where
1564     private Symbol findMethod(Env<AttrContext> env,
1565                               Type site,
1566                               Name name,
1567                               List<Type> argtypes,
1568                               List<Type> typeargtypes,
1569                               Type intype,
1570                               Symbol bestSoFar,
1571                               boolean allowBoxing,
1572                               boolean useVarargs,
1573                               boolean operator) {
1574         @SuppressWarnings({"unchecked","rawtypes"})
1575         List<Type>[] itypes = (List<Type>[])new List[] { List.<Type>nil(), List.<Type>nil() };
1576         InterfaceLookupPhase iphase = InterfaceLookupPhase.ABSTRACT_OK;
1577         for (TypeSymbol s : superclasses(intype)) {
1578             bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1579                     s.members(), bestSoFar, allowBoxing, useVarargs, operator, true);
1580             if (name == names.init) return bestSoFar;
1581             iphase = (iphase == null) ? null : iphase.update(s, this);
1582             if (iphase != null) {
1583                 for (Type itype : types.interfaces(s.type)) {
1584                     itypes[iphase.ordinal()] = types.union(types.closure(itype), itypes[iphase.ordinal()]);
1585                 }
1586             }
1587         }
1588 
1589         Symbol concrete = bestSoFar.kind < ERR &&
1590                 (bestSoFar.flags() & ABSTRACT) == 0 ?
1591                 bestSoFar : methodNotFound;
1592 
1593         for (InterfaceLookupPhase iphase2 : InterfaceLookupPhase.values()) {
1594             if (iphase2 == InterfaceLookupPhase.DEFAULT_OK && !allowDefaultMethods) break;
1595             //keep searching for abstract methods
1596             for (Type itype : itypes[iphase2.ordinal()]) {
1597                 if (!itype.isInterface()) continue; //skip j.l.Object (included by Types.closure())
1598                 if (iphase2 == InterfaceLookupPhase.DEFAULT_OK &&
1599                         (itype.tsym.flags() & DEFAULT) == 0) continue;
1600                 bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1601                         itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, operator, true);
1602                 if (concrete != bestSoFar &&
1603                         concrete.kind < ERR  && bestSoFar.kind < ERR &&
1604                         types.isSubSignature(concrete.type, bestSoFar.type)) {
1605                     //this is an hack - as javac does not do full membership checks
1606                     //most specific ends up comparing abstract methods that might have
1607                     //been implemented by some concrete method in a subclass and,
1608                     //because of raw override, it is possible for an abstract method
1609                     //to be more specific than the concrete method - so we need
1610                     //to explicitly call that out (see CR 6178365)
1611                     bestSoFar = concrete;
1612                 }
1613             }
1614         }
1615         return bestSoFar;
1616     }
1617 
1618     enum InterfaceLookupPhase {
1619         ABSTRACT_OK() {
1620             @Override
1621             InterfaceLookupPhase update(Symbol s, Resolve rs) {
1622                 //We should not look for abstract methods if receiver is a concrete class
1623                 //(as concrete classes are expected to implement all abstracts coming
1624                 //from superinterfaces)
1625                 if ((s.flags() & (ABSTRACT | INTERFACE | ENUM)) != 0) {
1626                     return this;
1627                 } else if (rs.allowDefaultMethods) {
1628                     return DEFAULT_OK;
1629                 } else {
1630                     return null;
1631                 }
1632             }
1633         },
1634         DEFAULT_OK() {
1635             @Override
1636             InterfaceLookupPhase update(Symbol s, Resolve rs) {
1637                 return this;
1638             }
1639         };
1640 
1641         abstract InterfaceLookupPhase update(Symbol s, Resolve rs);
1642     }
1643 
1644     /**
1645      * Return an Iterable object to scan the superclasses of a given type.
1646      * It's crucial that the scan is done lazily, as we don't want to accidentally
1647      * access more supertypes than strictly needed (as this could trigger completion
1648      * errors if some of the not-needed supertypes are missing/ill-formed).
1649      */
1650     Iterable<TypeSymbol> superclasses(final Type intype) {
1651         return new Iterable<TypeSymbol>() {
1652             public Iterator<TypeSymbol> iterator() {
1653                 return new Iterator<TypeSymbol>() {
1654 
1655                     List<TypeSymbol> seen = List.nil();
1656                     TypeSymbol currentSym = symbolFor(intype);
1657                     TypeSymbol prevSym = null;
1658 
1659                     public boolean hasNext() {
1660                         if (currentSym == syms.noSymbol) {
1661                             currentSym = symbolFor(types.supertype(prevSym.type));
1662                         }
1663                         return currentSym != null;
1664                     }
1665 
1666                     public TypeSymbol next() {
1667                         prevSym = currentSym;
1668                         currentSym = syms.noSymbol;
1669                         Assert.check(prevSym != null || prevSym != syms.noSymbol);
1670                         return prevSym;
1671                     }
1672 
1673                     public void remove() {
1674                         throw new UnsupportedOperationException();
1675                     }
1676 
1677                     TypeSymbol symbolFor(Type t) {
1678                         if (!t.hasTag(CLASS) &&
1679                                 !t.hasTag(TYPEVAR)) {
1680                             return null;
1681                         }
1682                         while (t.hasTag(TYPEVAR))
1683                             t = t.getUpperBound();
1684                         if (seen.contains(t.tsym)) {
1685                             //degenerate case in which we have a circular
1686                             //class hierarchy - because of ill-formed classfiles
1687                             return null;
1688                         }
1689                         seen = seen.prepend(t.tsym);
1690                         return t.tsym;
1691                     }
1692                 };
1693             }
1694         };
1695     }
1696 
1697     /** Find unqualified method matching given name, type and value arguments.
1698      *  @param env       The current environment.
1699      *  @param name      The method's name.
1700      *  @param argtypes  The method's value arguments.
1701      *  @param typeargtypes  The method's type arguments.
1702      *  @param allowBoxing Allow boxing conversions of arguments.
1703      *  @param useVarargs Box trailing arguments into an array for varargs.
1704      */
1705     Symbol findFun(Env<AttrContext> env, Name name,
1706                    List<Type> argtypes, List<Type> typeargtypes,
1707                    boolean allowBoxing, boolean useVarargs) {
1708         Symbol bestSoFar = methodNotFound;
1709         Symbol sym;
1710         Env<AttrContext> env1 = env;
1711         boolean staticOnly = false;
1712         while (env1.outer != null) {
1713             if (isStatic(env1)) staticOnly = true;
1714             sym = findMethod(
1715                 env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
1716                 allowBoxing, useVarargs, false);
1717             if (sym.exists()) {
1718                 if (staticOnly &&
1719                     sym.kind == MTH &&
1720                     sym.owner.kind == TYP &&
1721                     (sym.flags() & STATIC) == 0) return new StaticError(sym);
1722                 else return sym;
1723             } else if (sym.kind < bestSoFar.kind) {
1724                 bestSoFar = sym;
1725             }
1726             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
1727             env1 = env1.outer;
1728         }
1729 
1730         sym = findMethod(env, syms.predefClass.type, name, argtypes,
1731                          typeargtypes, allowBoxing, useVarargs, false);
1732         if (sym.exists())
1733             return sym;
1734 
1735         Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
1736         for (; e.scope != null; e = e.next()) {
1737             sym = e.sym;
1738             Type origin = e.getOrigin().owner.type;
1739             if (sym.kind == MTH) {
1740                 if (e.sym.owner.type != origin)
1741                     sym = sym.clone(e.getOrigin().owner);
1742                 if (!isAccessible(env, origin, sym))
1743                     sym = new AccessError(env, origin, sym);
1744                 bestSoFar = selectBest(env, origin,
1745                                        argtypes, typeargtypes,
1746                                        sym, bestSoFar,
1747                                        allowBoxing, useVarargs, false);
1748             }
1749         }
1750         if (bestSoFar.exists())
1751             return bestSoFar;
1752 
1753         e = env.toplevel.starImportScope.lookup(name);
1754         for (; e.scope != null; e = e.next()) {
1755             sym = e.sym;
1756             Type origin = e.getOrigin().owner.type;
1757             if (sym.kind == MTH) {
1758                 if (e.sym.owner.type != origin)
1759                     sym = sym.clone(e.getOrigin().owner);
1760                 if (!isAccessible(env, origin, sym))
1761                     sym = new AccessError(env, origin, sym);
1762                 bestSoFar = selectBest(env, origin,
1763                                        argtypes, typeargtypes,
1764                                        sym, bestSoFar,
1765                                        allowBoxing, useVarargs, false);
1766             }
1767         }
1768         return bestSoFar;
1769     }
1770 
1771     /** Load toplevel or member class with given fully qualified name and
1772      *  verify that it is accessible.
1773      *  @param env       The current environment.
1774      *  @param name      The fully qualified name of the class to be loaded.
1775      */
1776     Symbol loadClass(Env<AttrContext> env, Name name) {
1777         try {
1778             ClassSymbol c = reader.loadClass(name);
1779             return isAccessible(env, c) ? c : new AccessError(c);
1780         } catch (ClassReader.BadClassFile err) {
1781             throw err;
1782         } catch (CompletionFailure ex) {
1783             return typeNotFound;
1784         }
1785     }
1786 
1787 
1788     /**
1789      * Find a type declared in a scope (not inherited).  Return null
1790      * if none is found.
1791      *  @param env       The current environment.
1792      *  @param site      The original type from where the selection takes
1793      *                   place.
1794      *  @param name      The type's name.
1795      *  @param c         The class to search for the member type. This is
1796      *                   always a superclass or implemented interface of
1797      *                   site's class.
1798      */
1799     Symbol findImmediateMemberType(Env<AttrContext> env,
1800                                    Type site,
1801                                    Name name,
1802                                    TypeSymbol c) {
1803         Scope.Entry e = c.members().lookup(name);
1804         while (e.scope != null) {
1805             if (e.sym.kind == TYP) {
1806                 return isAccessible(env, site, e.sym)
1807                     ? e.sym
1808                     : new AccessError(env, site, e.sym);
1809             }
1810             e = e.next();
1811         }
1812         return null;
1813     }
1814 
1815     /** Find a member type inherited from a superclass or interface.
1816      *  @param env       The current environment.
1817      *  @param site      The original type from where the selection takes
1818      *                   place.
1819      *  @param name      The type's name.
1820      *  @param c         The class to search for the member type. This is
1821      *                   always a superclass or implemented interface of
1822      *                   site's class.
1823      */
1824     Symbol findInheritedMemberType(Env<AttrContext> env,
1825                                    Type site,
1826                                    Name name,
1827                                    TypeSymbol c) {
1828         Symbol bestSoFar = typeNotFound;
1829         Symbol sym;
1830         Type st = types.supertype(c.type);
1831         if (st != null && st.hasTag(CLASS)) {
1832             sym = findMemberType(env, site, name, st.tsym);
1833             if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1834         }
1835         for (List<Type> l = types.interfaces(c.type);
1836              bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
1837              l = l.tail) {
1838             sym = findMemberType(env, site, name, l.head.tsym);
1839             if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&
1840                 sym.owner != bestSoFar.owner)
1841                 bestSoFar = new AmbiguityError(bestSoFar, sym);
1842             else if (sym.kind < bestSoFar.kind)
1843                 bestSoFar = sym;
1844         }
1845         return bestSoFar;
1846     }
1847 
1848     /** Find qualified member type.
1849      *  @param env       The current environment.
1850      *  @param site      The original type from where the selection takes
1851      *                   place.
1852      *  @param name      The type's name.
1853      *  @param c         The class to search for the member type. This is
1854      *                   always a superclass or implemented interface of
1855      *                   site's class.
1856      */
1857     Symbol findMemberType(Env<AttrContext> env,
1858                           Type site,
1859                           Name name,
1860                           TypeSymbol c) {
1861         Symbol sym = findImmediateMemberType(env, site, name, c);
1862 
1863         if (sym != null)
1864             return sym;
1865 
1866         return findInheritedMemberType(env, site, name, c);
1867 
1868     }
1869 
1870     /** Find a global type in given scope and load corresponding class.
1871      *  @param env       The current environment.
1872      *  @param scope     The scope in which to look for the type.
1873      *  @param name      The type's name.
1874      */
1875     Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {
1876         Symbol bestSoFar = typeNotFound;
1877         for (Scope.Entry e = scope.lookup(name); e.scope != null; e = e.next()) {
1878             Symbol sym = loadClass(env, e.sym.flatName());
1879             if (bestSoFar.kind == TYP && sym.kind == TYP &&
1880                 bestSoFar != sym)
1881                 return new AmbiguityError(bestSoFar, sym);
1882             else if (sym.kind < bestSoFar.kind)
1883                 bestSoFar = sym;
1884         }
1885         return bestSoFar;
1886     }
1887 
1888     /** Find an unqualified type symbol.
1889      *  @param env       The current environment.
1890      *  @param name      The type's name.
1891      */
1892     Symbol findType(Env<AttrContext> env, Name name) {
1893         Symbol bestSoFar = typeNotFound;
1894         Symbol sym;
1895         boolean staticOnly = false;
1896         for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {
1897             // First, try the members declared in the class
1898             sym = findImmediateMemberType(env1, env1.enclClass.sym.type,
1899                                           name, env1.enclClass.sym);
1900             // Then try the type parameters
1901             if (sym == null) {
1902                 if (isStatic(env1)) staticOnly = true;
1903                 for (Scope.Entry e = env1.info.scope.lookup(name);
1904                      e.scope != null;
1905                      e = e.next()) {
1906                     if (e.sym.kind == TYP) {
1907                         if (staticOnly &&
1908                             e.sym.type.hasTag(TYPEVAR) &&
1909                             e.sym.owner.kind == TYP)
1910                             return new StaticError(e.sym);
1911                         return e.sym;
1912                     }
1913                 }
1914                 sym = findInheritedMemberType(env1, env1.enclClass.sym.type,
1915                                               name, env1.enclClass.sym);
1916             }
1917 
1918             if (staticOnly && sym.kind == TYP &&
1919                 sym.type.hasTag(CLASS) &&
1920                 sym.type.getEnclosingType().hasTag(CLASS) &&
1921                 env1.enclClass.sym.type.isParameterized() &&
1922                 sym.type.getEnclosingType().isParameterized())
1923                 return new StaticError(sym);
1924             else if (sym.exists()) return sym;
1925             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1926 
1927             JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass;
1928             if ((encl.sym.flags() & STATIC) != 0)
1929                 staticOnly = true;
1930         }
1931 
1932         if (!env.tree.hasTag(IMPORT)) {
1933             sym = findGlobalType(env, env.toplevel.namedImportScope, name);
1934             if (sym.exists()) return sym;
1935             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1936 
1937             sym = findGlobalType(env, env.toplevel.packge.members(), name);
1938             if (sym.exists()) return sym;
1939             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1940 
1941             sym = findGlobalType(env, env.toplevel.starImportScope, name);
1942             if (sym.exists()) return sym;
1943             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1944         }
1945 
1946         return bestSoFar;
1947     }
1948 
1949     /** Find an unqualified identifier which matches a specified kind set.
1950      *  @param env       The current environment.
1951      *  @param name      The identifier's name.
1952      *  @param kind      Indicates the possible symbol kinds
1953      *                   (a subset of VAL, TYP, PCK).
1954      */
1955     Symbol findIdent(Env<AttrContext> env, Name name, int kind) {
1956         Symbol bestSoFar = typeNotFound;
1957         Symbol sym;
1958 
1959         if ((kind & VAR) != 0) {
1960             sym = findVar(env, name);
1961             if (sym.exists()) return sym;
1962             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1963         }
1964 
1965         if ((kind & TYP) != 0) {
1966             sym = findType(env, name);
1967             if (sym.kind==TYP) {
1968                  reportDependence(env.enclClass.sym, sym);
1969             }
1970             if (sym.exists()) return sym;
1971             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1972         }
1973 
1974         if ((kind & PCK) != 0) return reader.enterPackage(name);
1975         else return bestSoFar;
1976     }
1977 
1978     /** Report dependencies.
1979      * @param from The enclosing class sym
1980      * @param to   The found identifier that the class depends on.
1981      */
1982     public void reportDependence(Symbol from, Symbol to) {
1983         // Override if you want to collect the reported dependencies.
1984     }
1985 
1986     /** Find an identifier in a package which matches a specified kind set.
1987      *  @param env       The current environment.
1988      *  @param name      The identifier's name.
1989      *  @param kind      Indicates the possible symbol kinds
1990      *                   (a nonempty subset of TYP, PCK).
1991      */
1992     Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck,
1993                               Name name, int kind) {
1994         Name fullname = TypeSymbol.formFullName(name, pck);
1995         Symbol bestSoFar = typeNotFound;
1996         PackageSymbol pack = null;
1997         if ((kind & PCK) != 0) {
1998             pack = reader.enterPackage(fullname);
1999             if (pack.exists()) return pack;
2000         }
2001         if ((kind & TYP) != 0) {
2002             Symbol sym = loadClass(env, fullname);
2003             if (sym.exists()) {
2004                 // don't allow programs to use flatnames
2005                 if (name == sym.name) return sym;
2006             }
2007             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
2008         }
2009         return (pack != null) ? pack : bestSoFar;
2010     }
2011 
2012     /** Find an identifier among the members of a given type `site'.
2013      *  @param env       The current environment.
2014      *  @param site      The type containing the symbol to be found.
2015      *  @param name      The identifier's name.
2016      *  @param kind      Indicates the possible symbol kinds
2017      *                   (a subset of VAL, TYP).
2018      */
2019     Symbol findIdentInType(Env<AttrContext> env, Type site,
2020                            Name name, int kind) {
2021         Symbol bestSoFar = typeNotFound;
2022         Symbol sym;
2023         if ((kind & VAR) != 0) {
2024             sym = findField(env, site, name, site.tsym);
2025             if (sym.exists()) return sym;
2026             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
2027         }
2028 
2029         if ((kind & TYP) != 0) {
2030             sym = findMemberType(env, site, name, site.tsym);
2031             if (sym.exists()) return sym;
2032             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
2033         }
2034         return bestSoFar;
2035     }
2036 
2037 /* ***************************************************************************
2038  *  Access checking
2039  *  The following methods convert ResolveErrors to ErrorSymbols, issuing
2040  *  an error message in the process
2041  ****************************************************************************/
2042 
2043     /** If `sym' is a bad symbol: report error and return errSymbol
2044      *  else pass through unchanged,
2045      *  additional arguments duplicate what has been used in trying to find the
2046      *  symbol {@literal (--> flyweight pattern)}. This improves performance since we
2047      *  expect misses to happen frequently.
2048      *
2049      *  @param sym       The symbol that was found, or a ResolveError.
2050      *  @param pos       The position to use for error reporting.
2051      *  @param location  The symbol the served as a context for this lookup
2052      *  @param site      The original type from where the selection took place.
2053      *  @param name      The symbol's name.
2054      *  @param qualified Did we get here through a qualified expression resolution?
2055      *  @param argtypes  The invocation's value arguments,
2056      *                   if we looked for a method.
2057      *  @param typeargtypes  The invocation's type arguments,
2058      *                   if we looked for a method.
2059      *  @param logResolveHelper helper class used to log resolve errors
2060      */
2061     Symbol accessInternal(Symbol sym,
2062                   DiagnosticPosition pos,
2063                   Symbol location,
2064                   Type site,
2065                   Name name,
2066                   boolean qualified,
2067                   List<Type> argtypes,
2068                   List<Type> typeargtypes,
2069                   LogResolveHelper logResolveHelper) {
2070         if (sym.kind >= AMBIGUOUS) {
2071             ResolveError errSym = (ResolveError)sym;
2072             sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol);
2073             argtypes = logResolveHelper.getArgumentTypes(errSym, sym, name, argtypes);
2074             if (logResolveHelper.resolveDiagnosticNeeded(site, argtypes, typeargtypes)) {
2075                 logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes);
2076             }
2077         }
2078         return sym;
2079     }
2080 
2081     /**
2082      * Variant of the generalized access routine, to be used for generating method
2083      * resolution diagnostics
2084      */
2085     Symbol accessMethod(Symbol sym,
2086                   DiagnosticPosition pos,
2087                   Symbol location,
2088                   Type site,
2089                   Name name,
2090                   boolean qualified,
2091                   List<Type> argtypes,
2092                   List<Type> typeargtypes) {
2093         return accessInternal(sym, pos, location, site, name, qualified, argtypes, typeargtypes, methodLogResolveHelper);
2094     }
2095 
2096     /** Same as original accessMethod(), but without location.
2097      */
2098     Symbol accessMethod(Symbol sym,
2099                   DiagnosticPosition pos,
2100                   Type site,
2101                   Name name,
2102                   boolean qualified,
2103                   List<Type> argtypes,
2104                   List<Type> typeargtypes) {
2105         return accessMethod(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes);
2106     }
2107 
2108     /**
2109      * Variant of the generalized access routine, to be used for generating variable,
2110      * type resolution diagnostics
2111      */
2112     Symbol accessBase(Symbol sym,
2113                   DiagnosticPosition pos,
2114                   Symbol location,
2115                   Type site,
2116                   Name name,
2117                   boolean qualified) {
2118         return accessInternal(sym, pos, location, site, name, qualified, List.<Type>nil(), null, basicLogResolveHelper);
2119     }
2120 
2121     /** Same as original accessBase(), but without location.
2122      */
2123     Symbol accessBase(Symbol sym,
2124                   DiagnosticPosition pos,
2125                   Type site,
2126                   Name name,
2127                   boolean qualified) {
2128         return accessBase(sym, pos, site.tsym, site, name, qualified);
2129     }
2130 
2131     interface LogResolveHelper {
2132         boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes);
2133         List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes);
2134     }
2135 
2136     LogResolveHelper basicLogResolveHelper = new LogResolveHelper() {
2137         public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2138             return !site.isErroneous();
2139         }
2140         public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2141             return argtypes;
2142         }
2143     };
2144 
2145     LogResolveHelper methodLogResolveHelper = new LogResolveHelper() {
2146         public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2147             return !site.isErroneous() &&
2148                         !Type.isErroneous(argtypes) &&
2149                         (typeargtypes == null || !Type.isErroneous(typeargtypes));
2150         }
2151         public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2152             return (syms.operatorNames.contains(name)) ?
2153                     argtypes :
2154                     Type.map(argtypes, new ResolveDeferredRecoveryMap(accessedSym));
2155         }
2156 
2157         class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap {
2158 
2159             public ResolveDeferredRecoveryMap(Symbol msym) {
2160                 deferredAttr.super(AttrMode.SPECULATIVE, msym, currentResolutionContext.step);
2161             }
2162 
2163             @Override
2164             protected Type typeOf(DeferredType dt) {
2165                 Type res = super.typeOf(dt);
2166                 if (!res.isErroneous()) {
2167                     switch (TreeInfo.skipParens(dt.tree).getTag()) {
2168                         case LAMBDA:
2169                         case REFERENCE:
2170                             return dt;
2171                         case CONDEXPR:
2172                             return res == Type.recoveryType ?
2173                                     dt : res;
2174                     }
2175                 }
2176                 return res;
2177             }
2178         }
2179     };
2180 
2181     /** Check that sym is not an abstract method.
2182      */
2183     void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
2184         if ((sym.flags() & ABSTRACT) != 0 && (sym.flags() & DEFAULT) == 0)
2185             log.error(pos, "abstract.cant.be.accessed.directly",
2186                       kindName(sym), sym, sym.location());
2187     }
2188 
2189 /* ***************************************************************************
2190  *  Debugging
2191  ****************************************************************************/
2192 
2193     /** print all scopes starting with scope s and proceeding outwards.
2194      *  used for debugging.
2195      */
2196     public void printscopes(Scope s) {
2197         while (s != null) {
2198             if (s.owner != null)
2199                 System.err.print(s.owner + ": ");
2200             for (Scope.Entry e = s.elems; e != null; e = e.sibling) {
2201                 if ((e.sym.flags() & ABSTRACT) != 0)
2202                     System.err.print("abstract ");
2203                 System.err.print(e.sym + " ");
2204             }
2205             System.err.println();
2206             s = s.next;
2207         }
2208     }
2209 
2210     void printscopes(Env<AttrContext> env) {
2211         while (env.outer != null) {
2212             System.err.println("------------------------------");
2213             printscopes(env.info.scope);
2214             env = env.outer;
2215         }
2216     }
2217 
2218     public void printscopes(Type t) {
2219         while (t.hasTag(CLASS)) {
2220             printscopes(t.tsym.members());
2221             t = types.supertype(t);
2222         }
2223     }
2224 
2225 /* ***************************************************************************
2226  *  Name resolution
2227  *  Naming conventions are as for symbol lookup
2228  *  Unlike the find... methods these methods will report access errors
2229  ****************************************************************************/
2230 
2231     /** Resolve an unqualified (non-method) identifier.
2232      *  @param pos       The position to use for error reporting.
2233      *  @param env       The environment current at the identifier use.
2234      *  @param name      The identifier's name.
2235      *  @param kind      The set of admissible symbol kinds for the identifier.
2236      */
2237     Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,
2238                         Name name, int kind) {
2239         return accessBase(
2240             findIdent(env, name, kind),
2241             pos, env.enclClass.sym.type, name, false);
2242     }
2243 
2244     /** Resolve an unqualified method identifier.
2245      *  @param pos       The position to use for error reporting.
2246      *  @param env       The environment current at the method invocation.
2247      *  @param name      The identifier's name.
2248      *  @param argtypes  The types of the invocation's value arguments.
2249      *  @param typeargtypes  The types of the invocation's type arguments.
2250      */
2251     Symbol resolveMethod(DiagnosticPosition pos,
2252                          Env<AttrContext> env,
2253                          Name name,
2254                          List<Type> argtypes,
2255                          List<Type> typeargtypes) {
2256         return lookupMethod(env, pos, env.enclClass.sym, resolveMethodCheck,
2257                 new BasicLookupHelper(name, env.enclClass.sym.type, argtypes, typeargtypes) {
2258                     @Override
2259                     Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2260                         return findFun(env, name, argtypes, typeargtypes,
2261                                 phase.isBoxingRequired(),
2262                                 phase.isVarargsRequired());
2263                     }});
2264     }
2265 
2266     /** Resolve a qualified method identifier
2267      *  @param pos       The position to use for error reporting.
2268      *  @param env       The environment current at the method invocation.
2269      *  @param site      The type of the qualifying expression, in which
2270      *                   identifier is searched.
2271      *  @param name      The identifier's name.
2272      *  @param argtypes  The types of the invocation's value arguments.
2273      *  @param typeargtypes  The types of the invocation's type arguments.
2274      */
2275     Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
2276                                   Type site, Name name, List<Type> argtypes,
2277                                   List<Type> typeargtypes) {
2278         return resolveQualifiedMethod(pos, env, site.tsym, site, name, argtypes, typeargtypes);
2279     }
2280     Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
2281                                   Symbol location, Type site, Name name, List<Type> argtypes,
2282                                   List<Type> typeargtypes) {
2283         return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes);
2284     }
2285     private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext,
2286                                   DiagnosticPosition pos, Env<AttrContext> env,
2287                                   Symbol location, Type site, Name name, List<Type> argtypes,
2288                                   List<Type> typeargtypes) {
2289         return lookupMethod(env, pos, location, resolveContext, new BasicLookupHelper(name, site, argtypes, typeargtypes) {
2290             @Override
2291             Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2292                 return findMethod(env, site, name, argtypes, typeargtypes,
2293                         phase.isBoxingRequired(),
2294                         phase.isVarargsRequired(), false);
2295             }
2296             @Override
2297             Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2298                 if (sym.kind >= AMBIGUOUS) {
2299                     sym = super.access(env, pos, location, sym);
2300                 } else if (allowMethodHandles) {
2301                     MethodSymbol msym = (MethodSymbol)sym;
2302                     if (msym.isSignaturePolymorphic(types)) {
2303                         return findPolymorphicSignatureInstance(env, sym, argtypes);
2304                     }
2305                 }
2306                 return sym;
2307             }
2308         });
2309     }
2310 
2311     /** Find or create an implicit method of exactly the given type (after erasure).
2312      *  Searches in a side table, not the main scope of the site.
2313      *  This emulates the lookup process required by JSR 292 in JVM.
2314      *  @param env       Attribution environment
2315      *  @param spMethod  signature polymorphic method - i.e. MH.invokeExact
2316      *  @param argtypes  The required argument types
2317      */
2318     Symbol findPolymorphicSignatureInstance(Env<AttrContext> env,
2319                                             final Symbol spMethod,
2320                                             List<Type> argtypes) {
2321         Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
2322                 (MethodSymbol)spMethod, currentResolutionContext, argtypes);
2323         for (Symbol sym : polymorphicSignatureScope.getElementsByName(spMethod.name)) {
2324             if (types.isSameType(mtype, sym.type)) {
2325                return sym;
2326             }
2327         }
2328 
2329         // create the desired method
2330         long flags = ABSTRACT | HYPOTHETICAL | spMethod.flags() & Flags.AccessFlags;
2331         Symbol msym = new MethodSymbol(flags, spMethod.name, mtype, spMethod.owner) {
2332             @Override
2333             public Symbol baseSymbol() {
2334                 return spMethod;
2335             }
2336         };
2337         polymorphicSignatureScope.enter(msym);
2338         return msym;
2339     }
2340 
2341     /** Resolve a qualified method identifier, throw a fatal error if not
2342      *  found.
2343      *  @param pos       The position to use for error reporting.
2344      *  @param env       The environment current at the method invocation.
2345      *  @param site      The type of the qualifying expression, in which
2346      *                   identifier is searched.
2347      *  @param name      The identifier's name.
2348      *  @param argtypes  The types of the invocation's value arguments.
2349      *  @param typeargtypes  The types of the invocation's type arguments.
2350      */
2351     public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env,
2352                                         Type site, Name name,
2353                                         List<Type> argtypes,
2354                                         List<Type> typeargtypes) {
2355         MethodResolutionContext resolveContext = new MethodResolutionContext();
2356         resolveContext.internalResolution = true;
2357         Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym,
2358                 site, name, argtypes, typeargtypes);
2359         if (sym.kind == MTH) return (MethodSymbol)sym;
2360         else throw new FatalError(
2361                  diags.fragment("fatal.err.cant.locate.meth",
2362                                 name));
2363     }
2364 
2365     /** Resolve constructor.
2366      *  @param pos       The position to use for error reporting.
2367      *  @param env       The environment current at the constructor invocation.
2368      *  @param site      The type of class for which a constructor is searched.
2369      *  @param argtypes  The types of the constructor invocation's value
2370      *                   arguments.
2371      *  @param typeargtypes  The types of the constructor invocation's type
2372      *                   arguments.
2373      */
2374     Symbol resolveConstructor(DiagnosticPosition pos,
2375                               Env<AttrContext> env,
2376                               Type site,
2377                               List<Type> argtypes,
2378                               List<Type> typeargtypes) {
2379         return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes);
2380     }
2381 
2382     private Symbol resolveConstructor(MethodResolutionContext resolveContext,
2383                               final DiagnosticPosition pos,
2384                               Env<AttrContext> env,
2385                               Type site,
2386                               List<Type> argtypes,
2387                               List<Type> typeargtypes) {
2388         return lookupMethod(env, pos, site.tsym, resolveContext, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2389             @Override
2390             Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2391                 return findConstructor(pos, env, site, argtypes, typeargtypes,
2392                         phase.isBoxingRequired(),
2393                         phase.isVarargsRequired());
2394             }
2395         });
2396     }
2397 
2398     /** Resolve a constructor, throw a fatal error if not found.
2399      *  @param pos       The position to use for error reporting.
2400      *  @param env       The environment current at the method invocation.
2401      *  @param site      The type to be constructed.
2402      *  @param argtypes  The types of the invocation's value arguments.
2403      *  @param typeargtypes  The types of the invocation's type arguments.
2404      */
2405     public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2406                                         Type site,
2407                                         List<Type> argtypes,
2408                                         List<Type> typeargtypes) {
2409         MethodResolutionContext resolveContext = new MethodResolutionContext();
2410         resolveContext.internalResolution = true;
2411         Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
2412         if (sym.kind == MTH) return (MethodSymbol)sym;
2413         else throw new FatalError(
2414                  diags.fragment("fatal.err.cant.locate.ctor", site));
2415     }
2416 
2417     Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2418                               Type site, List<Type> argtypes,
2419                               List<Type> typeargtypes,
2420                               boolean allowBoxing,
2421                               boolean useVarargs) {
2422         Symbol sym = findMethod(env, site,
2423                                     names.init, argtypes,
2424                                     typeargtypes, allowBoxing,
2425                                     useVarargs, false);
2426         chk.checkDeprecated(pos, env.info.scope.owner, sym);
2427         return sym;
2428     }
2429 
2430     /** Resolve constructor using diamond inference.
2431      *  @param pos       The position to use for error reporting.
2432      *  @param env       The environment current at the constructor invocation.
2433      *  @param site      The type of class for which a constructor is searched.
2434      *                   The scope of this class has been touched in attribution.
2435      *  @param argtypes  The types of the constructor invocation's value
2436      *                   arguments.
2437      *  @param typeargtypes  The types of the constructor invocation's type
2438      *                   arguments.
2439      */
2440     Symbol resolveDiamond(DiagnosticPosition pos,
2441                               Env<AttrContext> env,
2442                               Type site,
2443                               List<Type> argtypes,
2444                               List<Type> typeargtypes) {
2445         return lookupMethod(env, pos, site.tsym, resolveMethodCheck,
2446                 new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2447                     @Override
2448                     Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2449                         return findDiamond(env, site, argtypes, typeargtypes,
2450                                 phase.isBoxingRequired(),
2451                                 phase.isVarargsRequired());
2452                     }
2453                     @Override
2454                     Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2455                         if (sym.kind >= AMBIGUOUS) {
2456                             final JCDiagnostic details = sym.kind == WRONG_MTH ?
2457                                             ((InapplicableSymbolError)sym).errCandidate().details :
2458                                             null;
2459                             sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) {
2460                                 @Override
2461                                 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
2462                                         Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
2463                                     String key = details == null ?
2464                                         "cant.apply.diamond" :
2465                                         "cant.apply.diamond.1";
2466                                     return diags.create(dkind, log.currentSource(), pos, key,
2467                                             diags.fragment("diamond", site.tsym), details);
2468                                 }
2469                             };
2470                             sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
2471                             env.info.pendingResolutionPhase = currentResolutionContext.step;
2472                         }
2473                         return sym;
2474                     }});
2475     }
2476 
2477     /** This method scans all the constructor symbol in a given class scope -
2478      *  assuming that the original scope contains a constructor of the kind:
2479      *  {@code Foo(X x, Y y)}, where X,Y are class type-variables declared in Foo,
2480      *  a method check is executed against the modified constructor type:
2481      *  {@code <X,Y>Foo<X,Y>(X x, Y y)}. This is crucial in order to enable diamond
2482      *  inference. The inferred return type of the synthetic constructor IS
2483      *  the inferred type for the diamond operator.
2484      */
2485     private Symbol findDiamond(Env<AttrContext> env,
2486                               Type site,
2487                               List<Type> argtypes,
2488                               List<Type> typeargtypes,
2489                               boolean allowBoxing,
2490                               boolean useVarargs) {
2491         Symbol bestSoFar = methodNotFound;
2492         for (Scope.Entry e = site.tsym.members().lookup(names.init);
2493              e.scope != null;
2494              e = e.next()) {
2495             final Symbol sym = e.sym;
2496             //- System.out.println(" e " + e.sym);
2497             if (sym.kind == MTH &&
2498                 (sym.flags_field & SYNTHETIC) == 0) {
2499                     List<Type> oldParams = e.sym.type.hasTag(FORALL) ?
2500                             ((ForAll)sym.type).tvars :
2501                             List.<Type>nil();
2502                     Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
2503                             types.createMethodTypeWithReturn(sym.type.asMethodType(), site));
2504                     MethodSymbol newConstr = new MethodSymbol(sym.flags(), names.init, constrType, site.tsym) {
2505                         @Override
2506                         public Symbol baseSymbol() {
2507                             return sym;
2508                         }
2509                     };
2510                     bestSoFar = selectBest(env, site, argtypes, typeargtypes,
2511                             newConstr,
2512                             bestSoFar,
2513                             allowBoxing,
2514                             useVarargs,
2515                             false);
2516             }
2517         }
2518         return bestSoFar;
2519     }
2520 
2521 
2522 
2523     /** Resolve operator.
2524      *  @param pos       The position to use for error reporting.
2525      *  @param optag     The tag of the operation tree.
2526      *  @param env       The environment current at the operation.
2527      *  @param argtypes  The types of the operands.
2528      */
2529     Symbol resolveOperator(DiagnosticPosition pos, JCTree.Tag optag,
2530                            Env<AttrContext> env, List<Type> argtypes) {
2531         MethodResolutionContext prevResolutionContext = currentResolutionContext;
2532         try {
2533             currentResolutionContext = new MethodResolutionContext();
2534             Name name = treeinfo.operatorName(optag);
2535             env.info.pendingResolutionPhase = currentResolutionContext.step = BASIC;
2536             Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
2537                                     null, false, false, true);
2538             if (boxingEnabled && sym.kind >= WRONG_MTHS)
2539                 env.info.pendingResolutionPhase = currentResolutionContext.step = BOX;
2540                 sym = findMethod(env, syms.predefClass.type, name, argtypes,
2541                                  null, true, false, true);
2542             return accessMethod(sym, pos, env.enclClass.sym.type, name,
2543                           false, argtypes, null);
2544         }
2545         finally {
2546             currentResolutionContext = prevResolutionContext;
2547         }
2548     }
2549 
2550     /** Resolve operator.
2551      *  @param pos       The position to use for error reporting.
2552      *  @param optag     The tag of the operation tree.
2553      *  @param env       The environment current at the operation.
2554      *  @param arg       The type of the operand.
2555      */
2556     Symbol resolveUnaryOperator(DiagnosticPosition pos, JCTree.Tag optag, Env<AttrContext> env, Type arg) {
2557         return resolveOperator(pos, optag, env, List.of(arg));
2558     }
2559 
2560     /** Resolve binary operator.
2561      *  @param pos       The position to use for error reporting.
2562      *  @param optag     The tag of the operation tree.
2563      *  @param env       The environment current at the operation.
2564      *  @param left      The types of the left operand.
2565      *  @param right     The types of the right operand.
2566      */
2567     Symbol resolveBinaryOperator(DiagnosticPosition pos,
2568                                  JCTree.Tag optag,
2569                                  Env<AttrContext> env,
2570                                  Type left,
2571                                  Type right) {
2572         return resolveOperator(pos, optag, env, List.of(left, right));
2573     }
2574 
2575     /**
2576      * Resolution of member references is typically done as a single
2577      * overload resolution step, where the argument types A are inferred from
2578      * the target functional descriptor.
2579      *
2580      * If the member reference is a method reference with a type qualifier,
2581      * a two-step lookup process is performed. The first step uses the
2582      * expected argument list A, while the second step discards the first
2583      * type from A (which is treated as a receiver type).
2584      *
2585      * There are two cases in which inference is performed: (i) if the member
2586      * reference is a constructor reference and the qualifier type is raw - in
2587      * which case diamond inference is used to infer a parameterization for the
2588      * type qualifier; (ii) if the member reference is an unbound reference
2589      * where the type qualifier is raw - in that case, during the unbound lookup
2590      * the receiver argument type is used to infer an instantiation for the raw
2591      * qualifier type.
2592      *
2593      * When a multi-step resolution process is exploited, it is an error
2594      * if two candidates are found (ambiguity).
2595      *
2596      * This routine returns a pair (T,S), where S is the member reference symbol,
2597      * and T is the type of the class in which S is defined. This is necessary as
2598      * the type T might be dynamically inferred (i.e. if constructor reference
2599      * has a raw qualifier).
2600      */
2601     Pair<Symbol, ReferenceLookupHelper> resolveMemberReference(DiagnosticPosition pos,
2602                                   Env<AttrContext> env,
2603                                   JCMemberReference referenceTree,
2604                                   Type site,
2605                                   Name name, List<Type> argtypes,
2606                                   List<Type> typeargtypes,
2607                                   boolean boxingAllowed,
2608                                   MethodCheck methodCheck) {
2609         MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC;
2610 
2611         ReferenceLookupHelper boundLookupHelper;
2612         if (!name.equals(names.init)) {
2613             //method reference
2614             boundLookupHelper =
2615                     new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
2616         } else if (site.hasTag(ARRAY)) {
2617             //array constructor reference
2618             boundLookupHelper =
2619                     new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
2620         } else {
2621             //class constructor reference
2622             boundLookupHelper =
2623                     new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
2624         }
2625 
2626         //step 1 - bound lookup
2627         Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
2628         Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, methodCheck, boundLookupHelper);
2629 
2630         //step 2 - unbound lookup
2631         ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup();
2632         Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
2633         Symbol unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, methodCheck, unboundLookupHelper);
2634 
2635         //merge results
2636         Pair<Symbol, ReferenceLookupHelper> res;
2637         if (!lookupSuccess(unboundSym)) {
2638             res = new Pair<Symbol, ReferenceLookupHelper>(boundSym, boundLookupHelper);
2639             env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase;
2640         } else if (lookupSuccess(boundSym)) {
2641             res = new Pair<Symbol, ReferenceLookupHelper>(ambiguityError(boundSym, unboundSym), boundLookupHelper);
2642             env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase;
2643         } else {
2644             res = new Pair<Symbol, ReferenceLookupHelper>(unboundSym, unboundLookupHelper);
2645             env.info.pendingResolutionPhase = unboundEnv.info.pendingResolutionPhase;
2646         }
2647 
2648         return res;
2649     }
2650     //private
2651         boolean lookupSuccess(Symbol s) {
2652             return s.kind == MTH || s.kind == AMBIGUOUS;
2653         }
2654 
2655     /**
2656      * Helper for defining custom method-like lookup logic; a lookup helper
2657      * provides hooks for (i) the actual lookup logic and (ii) accessing the
2658      * lookup result (this step might result in compiler diagnostics to be generated)
2659      */
2660     abstract class LookupHelper {
2661 
2662         /** name of the symbol to lookup */
2663         Name name;
2664 
2665         /** location in which the lookup takes place */
2666         Type site;
2667 
2668         /** actual types used during the lookup */
2669         List<Type> argtypes;
2670 
2671         /** type arguments used during the lookup */
2672         List<Type> typeargtypes;
2673 
2674         /** Max overload resolution phase handled by this helper */
2675         MethodResolutionPhase maxPhase;
2676 
2677         LookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2678             this.name = name;
2679             this.site = site;
2680             this.argtypes = argtypes;
2681             this.typeargtypes = typeargtypes;
2682             this.maxPhase = maxPhase;
2683         }
2684 
2685         /**
2686          * Should lookup stop at given phase with given result
2687          */
2688         protected boolean shouldStop(Symbol sym, MethodResolutionPhase phase) {
2689             return phase.ordinal() > maxPhase.ordinal() ||
2690                     sym.kind < ERRONEOUS || sym.kind == AMBIGUOUS;
2691         }
2692 
2693         /**
2694          * Search for a symbol under a given overload resolution phase - this method
2695          * is usually called several times, once per each overload resolution phase
2696          */
2697         abstract Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase);
2698 
2699         /**
2700          * Validate the result of the lookup
2701          */
2702         abstract Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym);
2703     }
2704 
2705     abstract class BasicLookupHelper extends LookupHelper {
2706 
2707         BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) {
2708             super(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY);
2709         }
2710 
2711         @Override
2712         Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2713             if (sym.kind == AMBIGUOUS) {
2714                 AmbiguityError a_err = (AmbiguityError)sym;
2715                 sym = a_err.mergeAbstracts(site);
2716             }
2717             if (sym.kind >= AMBIGUOUS) {
2718                 //if nothing is found return the 'first' error
2719                 sym = accessMethod(sym, pos, location, site, name, true, argtypes, typeargtypes);
2720             }
2721             return sym;
2722         }
2723     }
2724 
2725     /**
2726      * Helper class for member reference lookup. A reference lookup helper
2727      * defines the basic logic for member reference lookup; a method gives
2728      * access to an 'unbound' helper used to perform an unbound member
2729      * reference lookup.
2730      */
2731     abstract class ReferenceLookupHelper extends LookupHelper {
2732 
2733         /** The member reference tree */
2734         JCMemberReference referenceTree;
2735 
2736         ReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
2737                 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2738             super(name, site, argtypes, typeargtypes, maxPhase);
2739             this.referenceTree = referenceTree;
2740 
2741         }
2742 
2743         /**
2744          * Returns an unbound version of this lookup helper. By default, this
2745          * method returns an dummy lookup helper.
2746          */
2747         ReferenceLookupHelper unboundLookup() {
2748             //dummy loopkup helper that always return 'methodNotFound'
2749             return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
2750                 @Override
2751                 ReferenceLookupHelper unboundLookup() {
2752                     return this;
2753                 }
2754                 @Override
2755                 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2756                     return methodNotFound;
2757                 }
2758                 @Override
2759                 ReferenceKind referenceKind(Symbol sym) {
2760                     Assert.error();
2761                     return null;
2762                 }
2763             };
2764         }
2765 
2766         /**
2767          * Get the kind of the member reference
2768          */
2769         abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym);
2770 
2771         Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2772             if (sym.kind == AMBIGUOUS) {
2773                 AmbiguityError a_err = (AmbiguityError)sym;
2774                 sym = a_err.mergeAbstracts(site);
2775             }
2776             //skip error reporting
2777             return sym;
2778         }
2779     }
2780 
2781     /**
2782      * Helper class for method reference lookup. The lookup logic is based
2783      * upon Resolve.findMethod; in certain cases, this helper class has a
2784      * corresponding unbound helper class (see UnboundMethodReferenceLookupHelper).
2785      * In such cases, non-static lookup results are thrown away.
2786      */
2787     class MethodReferenceLookupHelper extends ReferenceLookupHelper {
2788 
2789         MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
2790                 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2791             super(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
2792         }
2793 
2794         @Override
2795         final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2796             return findMethod(env, site, name, argtypes, typeargtypes,
2797                     phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
2798         }
2799 
2800         @Override
2801         ReferenceLookupHelper unboundLookup() {
2802             if (TreeInfo.isStaticSelector(referenceTree.expr, names) &&
2803                     argtypes.nonEmpty() &&
2804                     (argtypes.head.hasTag(NONE) || types.isSubtypeUnchecked(argtypes.head, site))) {
2805                 return new UnboundMethodReferenceLookupHelper(referenceTree, name,
2806                         site, argtypes, typeargtypes, maxPhase);
2807             } else {
2808                 return super.unboundLookup();
2809             }
2810         }
2811 
2812         @Override
2813         ReferenceKind referenceKind(Symbol sym) {
2814             if (sym.isStatic()) {
2815                 return ReferenceKind.STATIC;
2816             } else {
2817                 Name selName = TreeInfo.name(referenceTree.getQualifierExpression());
2818                 return selName != null && selName == names._super ?
2819                         ReferenceKind.SUPER :
2820                         ReferenceKind.BOUND;
2821             }
2822         }
2823     }
2824 
2825     /**
2826      * Helper class for unbound method reference lookup. Essentially the same
2827      * as the basic method reference lookup helper; main difference is that static
2828      * lookup results are thrown away. If qualifier type is raw, an attempt to
2829      * infer a parameterized type is made using the first actual argument (that
2830      * would otherwise be ignored during the lookup).
2831      */
2832     class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper {
2833 
2834         UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
2835                 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2836             super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase);
2837             if (site.isRaw() && !argtypes.head.hasTag(NONE)) {
2838                 Type asSuperSite = types.asSuper(argtypes.head, site.tsym);
2839                 this.site = asSuperSite;
2840             }
2841         }
2842 
2843         @Override
2844         ReferenceLookupHelper unboundLookup() {
2845             return this;
2846         }
2847 
2848         @Override
2849         ReferenceKind referenceKind(Symbol sym) {
2850             return ReferenceKind.UNBOUND;
2851         }
2852     }
2853 
2854     /**
2855      * Helper class for array constructor lookup; an array constructor lookup
2856      * is simulated by looking up a method that returns the array type specified
2857      * as qualifier, and that accepts a single int parameter (size of the array).
2858      */
2859     class ArrayConstructorReferenceLookupHelper extends ReferenceLookupHelper {
2860 
2861         ArrayConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
2862                 List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2863             super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
2864         }
2865 
2866         @Override
2867         protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2868             Scope sc = new Scope(syms.arrayClass);
2869             MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym);
2870             arrayConstr.type = new MethodType(List.of(syms.intType), site, List.<Type>nil(), syms.methodClass);
2871             sc.enter(arrayConstr);
2872             return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false, false);
2873         }
2874 
2875         @Override
2876         ReferenceKind referenceKind(Symbol sym) {
2877             return ReferenceKind.ARRAY_CTOR;
2878         }
2879     }
2880 
2881     /**
2882      * Helper class for constructor reference lookup. The lookup logic is based
2883      * upon either Resolve.findMethod or Resolve.findDiamond - depending on
2884      * whether the constructor reference needs diamond inference (this is the case
2885      * if the qualifier type is raw). A special erroneous symbol is returned
2886      * if the lookup returns the constructor of an inner class and there's no
2887      * enclosing instance in scope.
2888      */
2889     class ConstructorReferenceLookupHelper extends ReferenceLookupHelper {
2890 
2891         boolean needsInference;
2892 
2893         ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
2894                 List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2895             super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
2896             if (site.isRaw()) {
2897                 this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym);
2898                 needsInference = true;
2899             }
2900         }
2901 
2902         @Override
2903         protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2904             Symbol sym = needsInference ?
2905                 findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
2906                 findMethod(env, site, name, argtypes, typeargtypes,
2907                         phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
2908             return sym.kind != MTH ||
2909                           site.getEnclosingType().hasTag(NONE) ||
2910                           hasEnclosingInstance(env, site) ?
2911                           sym : new InvalidSymbolError(Kinds.MISSING_ENCL, sym, null) {
2912                     @Override
2913                     JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
2914                        return diags.create(dkind, log.currentSource(), pos,
2915                             "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType());
2916                     }
2917                 };
2918         }
2919 
2920         @Override
2921         ReferenceKind referenceKind(Symbol sym) {
2922             return site.getEnclosingType().hasTag(NONE) ?
2923                     ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER;
2924         }
2925     }
2926 
2927     /**
2928      * Main overload resolution routine. On each overload resolution step, a
2929      * lookup helper class is used to perform the method/constructor lookup;
2930      * at the end of the lookup, the helper is used to validate the results
2931      * (this last step might trigger overload resolution diagnostics).
2932      */
2933     Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, MethodCheck methodCheck, LookupHelper lookupHelper) {
2934         MethodResolutionContext resolveContext = new MethodResolutionContext();
2935         resolveContext.methodCheck = methodCheck;
2936         return lookupMethod(env, pos, location, resolveContext, lookupHelper);
2937     }
2938 
2939     Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location,
2940             MethodResolutionContext resolveContext, LookupHelper lookupHelper) {
2941         MethodResolutionContext prevResolutionContext = currentResolutionContext;
2942         try {
2943             Symbol bestSoFar = methodNotFound;
2944             currentResolutionContext = resolveContext;
2945             for (MethodResolutionPhase phase : methodResolutionSteps) {
2946                 if (!phase.isApplicable(boxingEnabled, varargsEnabled) ||
2947                         lookupHelper.shouldStop(bestSoFar, phase)) break;
2948                 MethodResolutionPhase prevPhase = currentResolutionContext.step;
2949                 Symbol prevBest = bestSoFar;
2950                 currentResolutionContext.step = phase;
2951                 bestSoFar = phase.mergeResults(bestSoFar, lookupHelper.lookup(env, phase));
2952                 env.info.pendingResolutionPhase = (prevBest == bestSoFar) ? prevPhase : phase;
2953             }
2954             return lookupHelper.access(env, pos, location, bestSoFar);
2955         } finally {
2956             currentResolutionContext = prevResolutionContext;
2957         }
2958     }
2959 
2960     /**
2961      * Resolve `c.name' where name == this or name == super.
2962      * @param pos           The position to use for error reporting.
2963      * @param env           The environment current at the expression.
2964      * @param c             The qualifier.
2965      * @param name          The identifier's name.
2966      */
2967     Symbol resolveSelf(DiagnosticPosition pos,
2968                        Env<AttrContext> env,
2969                        TypeSymbol c,
2970                        Name name) {
2971         Env<AttrContext> env1 = env;
2972         boolean staticOnly = false;
2973         while (env1.outer != null) {
2974             if (isStatic(env1)) staticOnly = true;
2975             if (env1.enclClass.sym == c) {
2976                 Symbol sym = env1.info.scope.lookup(name).sym;
2977                 if (sym != null) {
2978                     if (staticOnly) sym = new StaticError(sym);
2979                     return accessBase(sym, pos, env.enclClass.sym.type,
2980                                   name, true);
2981                 }
2982             }
2983             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
2984             env1 = env1.outer;
2985         }
2986         if (allowDefaultMethods && c.isInterface() &&
2987                 name == names._super && !isStatic(env) &&
2988                 types.isDirectSuperInterface(c, env.enclClass.sym)) {
2989             //this might be a default super call if one of the superinterfaces is 'c'
2990             for (Type t : pruneInterfaces(env.enclClass.type)) {
2991                 if (t.tsym == c) {
2992                     env.info.defaultSuperCallSite = t;
2993                     return new VarSymbol(0, names._super,
2994                             types.asSuper(env.enclClass.type, c), env.enclClass.sym);
2995                 }
2996             }
2997             //find a direct superinterface that is a subtype of 'c'
2998             for (Type i : types.interfaces(env.enclClass.type)) {
2999                 if (i.tsym.isSubClass(c, types) && i.tsym != c) {
3000                     log.error(pos, "illegal.default.super.call", c,
3001                             diags.fragment("redundant.supertype", c, i));
3002                     return syms.errSymbol;
3003                 }
3004             }
3005             Assert.error();
3006         }
3007         log.error(pos, "not.encl.class", c);
3008         return syms.errSymbol;
3009     }
3010     //where
3011     private List<Type> pruneInterfaces(Type t) {
3012         ListBuffer<Type> result = ListBuffer.lb();
3013         for (Type t1 : types.interfaces(t)) {
3014             boolean shouldAdd = true;
3015             for (Type t2 : types.interfaces(t)) {
3016                 if (t1 != t2 && types.isSubtypeNoCapture(t2, t1)) {
3017                     shouldAdd = false;
3018                 }
3019             }
3020             if (shouldAdd) {
3021                 result.append(t1);
3022             }
3023         }
3024         return result.toList();
3025     }
3026 
3027 
3028     /**
3029      * Resolve `c.this' for an enclosing class c that contains the
3030      * named member.
3031      * @param pos           The position to use for error reporting.
3032      * @param env           The environment current at the expression.
3033      * @param member        The member that must be contained in the result.
3034      */
3035     Symbol resolveSelfContaining(DiagnosticPosition pos,
3036                                  Env<AttrContext> env,
3037                                  Symbol member,
3038                                  boolean isSuperCall) {
3039         Symbol sym = resolveSelfContainingInternal(env, member, isSuperCall);
3040         if (sym == null) {
3041             log.error(pos, "encl.class.required", member);
3042             return syms.errSymbol;
3043         } else {
3044             return accessBase(sym, pos, env.enclClass.sym.type, sym.name, true);
3045         }
3046     }
3047 
3048     boolean hasEnclosingInstance(Env<AttrContext> env, Type type) {
3049         Symbol encl = resolveSelfContainingInternal(env, type.tsym, false);
3050         return encl != null && encl.kind < ERRONEOUS;
3051     }
3052 
3053     private Symbol resolveSelfContainingInternal(Env<AttrContext> env,
3054                                  Symbol member,
3055                                  boolean isSuperCall) {
3056         Name name = names._this;
3057         Env<AttrContext> env1 = isSuperCall ? env.outer : env;
3058         boolean staticOnly = false;
3059         if (env1 != null) {
3060             while (env1 != null && env1.outer != null) {
3061                 if (isStatic(env1)) staticOnly = true;
3062                 if (env1.enclClass.sym.isSubClass(member.owner, types)) {
3063                     Symbol sym = env1.info.scope.lookup(name).sym;
3064                     if (sym != null) {
3065                         if (staticOnly) sym = new StaticError(sym);
3066                         return sym;
3067                     }
3068                 }
3069                 if ((env1.enclClass.sym.flags() & STATIC) != 0)
3070                     staticOnly = true;
3071                 env1 = env1.outer;
3072             }
3073         }
3074         return null;
3075     }
3076 
3077     /**
3078      * Resolve an appropriate implicit this instance for t's container.
3079      * JLS 8.8.5.1 and 15.9.2
3080      */
3081     Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) {
3082         return resolveImplicitThis(pos, env, t, false);
3083     }
3084 
3085     Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t, boolean isSuperCall) {
3086         Type thisType = (((t.tsym.owner.kind & (MTH|VAR)) != 0)
3087                          ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this)
3088                          : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type;
3089         if (env.info.isSelfCall && thisType.tsym == env.enclClass.sym)
3090             log.error(pos, "cant.ref.before.ctor.called", "this");
3091         return thisType;
3092     }
3093 
3094 /* ***************************************************************************
3095  *  ResolveError classes, indicating error situations when accessing symbols
3096  ****************************************************************************/
3097 
3098     //used by TransTypes when checking target type of synthetic cast
3099     public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
3100         AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
3101         logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
3102     }
3103     //where
3104     private void logResolveError(ResolveError error,
3105             DiagnosticPosition pos,
3106             Symbol location,
3107             Type site,
3108             Name name,
3109             List<Type> argtypes,
3110             List<Type> typeargtypes) {
3111         JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
3112                 pos, location, site, name, argtypes, typeargtypes);
3113         if (d != null) {
3114             d.setFlag(DiagnosticFlag.RESOLVE_ERROR);
3115             log.report(d);
3116         }
3117     }
3118 
3119     private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
3120 
3121     public Object methodArguments(List<Type> argtypes) {
3122         if (argtypes == null || argtypes.isEmpty()) {
3123             return noArgs;
3124         } else {
3125             ListBuffer<Object> diagArgs = ListBuffer.lb();
3126             for (Type t : argtypes) {
3127                 if (t.hasTag(DEFERRED)) {
3128                     diagArgs.append(((DeferredAttr.DeferredType)t).tree);
3129                 } else {
3130                     diagArgs.append(t);
3131                 }
3132             }
3133             return diagArgs;
3134         }
3135     }
3136 
3137     /**
3138      * Root class for resolution errors. Subclass of ResolveError
3139      * represent a different kinds of resolution error - as such they must
3140      * specify how they map into concrete compiler diagnostics.
3141      */
3142     abstract class ResolveError extends Symbol {
3143 
3144         /** The name of the kind of error, for debugging only. */
3145         final String debugName;
3146 
3147         ResolveError(int kind, String debugName) {
3148             super(kind, 0, null, null, null);
3149             this.debugName = debugName;
3150         }
3151 
3152         @Override
3153         public <R, P> R accept(ElementVisitor<R, P> v, P p) {
3154             throw new AssertionError();
3155         }
3156 
3157         @Override
3158         public String toString() {
3159             return debugName;
3160         }
3161 
3162         @Override
3163         public boolean exists() {
3164             return false;
3165         }
3166 
3167         /**
3168          * Create an external representation for this erroneous symbol to be
3169          * used during attribution - by default this returns the symbol of a
3170          * brand new error type which stores the original type found
3171          * during resolution.
3172          *
3173          * @param name     the name used during resolution
3174          * @param location the location from which the symbol is accessed
3175          */
3176         protected Symbol access(Name name, TypeSymbol location) {
3177             return types.createErrorType(name, location, syms.errSymbol.type).tsym;
3178         }
3179 
3180         /**
3181          * Create a diagnostic representing this resolution error.
3182          *
3183          * @param dkind     The kind of the diagnostic to be created (e.g error).
3184          * @param pos       The position to be used for error reporting.
3185          * @param site      The original type from where the selection took place.
3186          * @param name      The name of the symbol to be resolved.
3187          * @param argtypes  The invocation's value arguments,
3188          *                  if we looked for a method.
3189          * @param typeargtypes  The invocation's type arguments,
3190          *                      if we looked for a method.
3191          */
3192         abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3193                 DiagnosticPosition pos,
3194                 Symbol location,
3195                 Type site,
3196                 Name name,
3197                 List<Type> argtypes,
3198                 List<Type> typeargtypes);
3199     }
3200 
3201     /**
3202      * This class is the root class of all resolution errors caused by
3203      * an invalid symbol being found during resolution.
3204      */
3205     abstract class InvalidSymbolError extends ResolveError {
3206 
3207         /** The invalid symbol found during resolution */
3208         Symbol sym;
3209 
3210         InvalidSymbolError(int kind, Symbol sym, String debugName) {
3211             super(kind, debugName);
3212             this.sym = sym;
3213         }
3214 
3215         @Override
3216         public boolean exists() {
3217             return true;
3218         }
3219 
3220         @Override
3221         public String toString() {
3222              return super.toString() + " wrongSym=" + sym;
3223         }
3224 
3225         @Override
3226         public Symbol access(Name name, TypeSymbol location) {
3227             if ((sym.kind & ERRONEOUS) == 0 && (sym.kind & TYP) != 0)
3228                 return types.createErrorType(name, location, sym.type).tsym;
3229             else
3230                 return sym;
3231         }
3232     }
3233 
3234     /**
3235      * InvalidSymbolError error class indicating that a symbol matching a
3236      * given name does not exists in a given site.
3237      */
3238     class SymbolNotFoundError extends ResolveError {
3239 
3240         SymbolNotFoundError(int kind) {
3241             super(kind, "symbol not found error");
3242         }
3243 
3244         @Override
3245         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3246                 DiagnosticPosition pos,
3247                 Symbol location,
3248                 Type site,
3249                 Name name,
3250                 List<Type> argtypes,
3251                 List<Type> typeargtypes) {
3252             argtypes = argtypes == null ? List.<Type>nil() : argtypes;
3253             typeargtypes = typeargtypes == null ? List.<Type>nil() : typeargtypes;
3254             if (name == names.error)
3255                 return null;
3256 
3257             if (syms.operatorNames.contains(name)) {
3258                 boolean isUnaryOp = argtypes.size() == 1;
3259                 String key = argtypes.size() == 1 ?
3260                     "operator.cant.be.applied" :
3261                     "operator.cant.be.applied.1";
3262                 Type first = argtypes.head;
3263                 Type second = !isUnaryOp ? argtypes.tail.head : null;
3264                 return diags.create(dkind, log.currentSource(), pos,
3265                         key, name, first, second);
3266             }
3267             boolean hasLocation = false;
3268             if (location == null) {
3269                 location = site.tsym;
3270             }
3271             if (!location.name.isEmpty()) {
3272                 if (location.kind == PCK && !site.tsym.exists()) {
3273                     return diags.create(dkind, log.currentSource(), pos,
3274                         "doesnt.exist", location);
3275                 }
3276                 hasLocation = !location.name.equals(names._this) &&
3277                         !location.name.equals(names._super);
3278             }
3279             boolean isConstructor = kind == ABSENT_MTH && name == names.init;
3280             KindName kindname = isConstructor ? KindName.CONSTRUCTOR : absentKind(kind);
3281             Name idname = isConstructor ? site.tsym.name : name;
3282             String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
3283             if (hasLocation) {
3284                 return diags.create(dkind, log.currentSource(), pos,
3285                         errKey, kindname, idname, //symbol kindname, name
3286                         typeargtypes, args(argtypes), //type parameters and arguments (if any)
3287                         getLocationDiag(location, site)); //location kindname, type
3288             }
3289             else {
3290                 return diags.create(dkind, log.currentSource(), pos,
3291                         errKey, kindname, idname, //symbol kindname, name
3292                         typeargtypes, args(argtypes)); //type parameters and arguments (if any)
3293             }
3294         }
3295         //where
3296         private Object args(List<Type> args) {
3297             return args.isEmpty() ? args : methodArguments(args);
3298         }
3299 
3300         private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) {
3301             String key = "cant.resolve";
3302             String suffix = hasLocation ? ".location" : "";
3303             switch (kindname) {
3304                 case METHOD:
3305                 case CONSTRUCTOR: {
3306                     suffix += ".args";
3307                     suffix += hasTypeArgs ? ".params" : "";
3308                 }
3309             }
3310             return key + suffix;
3311         }
3312         private JCDiagnostic getLocationDiag(Symbol location, Type site) {
3313             if (location.kind == VAR) {
3314                 return diags.fragment("location.1",
3315                     kindName(location),
3316                     location,
3317                     location.type);
3318             } else {
3319                 return diags.fragment("location",
3320                     typeKindName(site),
3321                     site,
3322                     null);
3323             }
3324         }
3325     }
3326 
3327     /**
3328      * InvalidSymbolError error class indicating that a given symbol
3329      * (either a method, a constructor or an operand) is not applicable
3330      * given an actual arguments/type argument list.
3331      */
3332     class InapplicableSymbolError extends ResolveError {
3333 
3334         protected MethodResolutionContext resolveContext;
3335 
3336         InapplicableSymbolError(MethodResolutionContext context) {
3337             this(WRONG_MTH, "inapplicable symbol error", context);
3338         }
3339 
3340         protected InapplicableSymbolError(int kind, String debugName, MethodResolutionContext context) {
3341             super(kind, debugName);
3342             this.resolveContext = context;
3343         }
3344 
3345         @Override
3346         public String toString() {
3347             return super.toString();
3348         }
3349 
3350         @Override
3351         public boolean exists() {
3352             return true;
3353         }
3354 
3355         @Override
3356         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3357                 DiagnosticPosition pos,
3358                 Symbol location,
3359                 Type site,
3360                 Name name,
3361                 List<Type> argtypes,
3362                 List<Type> typeargtypes) {
3363             if (name == names.error)
3364                 return null;
3365 
3366             if (syms.operatorNames.contains(name)) {
3367                 boolean isUnaryOp = argtypes.size() == 1;
3368                 String key = argtypes.size() == 1 ?
3369                     "operator.cant.be.applied" :
3370                     "operator.cant.be.applied.1";
3371                 Type first = argtypes.head;
3372                 Type second = !isUnaryOp ? argtypes.tail.head : null;
3373                 return diags.create(dkind, log.currentSource(), pos,
3374                         key, name, first, second);
3375             }
3376             else {
3377                 Candidate c = errCandidate();
3378                 Symbol ws = c.sym.asMemberOf(site, types);
3379                 return diags.create(dkind, log.currentSource(), pos,
3380                           "cant.apply.symbol",
3381                           kindName(ws),
3382                           ws.name == names.init ? ws.owner.name : ws.name,
3383                           methodArguments(ws.type.getParameterTypes()),
3384                           methodArguments(argtypes),
3385                           kindName(ws.owner),
3386                           ws.owner.type,
3387                           c.details);
3388             }
3389         }
3390 
3391         @Override
3392         public Symbol access(Name name, TypeSymbol location) {
3393             return types.createErrorType(name, location, syms.errSymbol.type).tsym;
3394         }
3395 
3396         private Candidate errCandidate() {
3397             Candidate bestSoFar = null;
3398             for (Candidate c : resolveContext.candidates) {
3399                 if (c.isApplicable()) continue;
3400                 bestSoFar = c;
3401             }
3402             Assert.checkNonNull(bestSoFar);
3403             return bestSoFar;
3404         }
3405     }
3406 
3407     /**
3408      * ResolveError error class indicating that a set of symbols
3409      * (either methods, constructors or operands) is not applicable
3410      * given an actual arguments/type argument list.
3411      */
3412     class InapplicableSymbolsError extends InapplicableSymbolError {
3413 
3414         InapplicableSymbolsError(MethodResolutionContext context) {
3415             super(WRONG_MTHS, "inapplicable symbols", context);
3416         }
3417 
3418         @Override
3419         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3420                 DiagnosticPosition pos,
3421                 Symbol location,
3422                 Type site,
3423                 Name name,
3424                 List<Type> argtypes,
3425                 List<Type> typeargtypes) {
3426             if (!resolveContext.candidates.isEmpty()) {
3427                 JCDiagnostic err = diags.create(dkind,
3428                         log.currentSource(),
3429                         pos,
3430                         "cant.apply.symbols",
3431                         name == names.init ? KindName.CONSTRUCTOR : absentKind(kind),
3432                         name == names.init ? site.tsym.name : name,
3433                         methodArguments(argtypes));
3434                 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site));
3435             } else {
3436                 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
3437                     location, site, name, argtypes, typeargtypes);
3438             }
3439         }
3440 
3441         //where
3442         List<JCDiagnostic> candidateDetails(Type site) {
3443             Map<Symbol, JCDiagnostic> details = new LinkedHashMap<Symbol, JCDiagnostic>();
3444             for (Candidate c : resolveContext.candidates) {
3445                 if (c.isApplicable()) continue;
3446                 JCDiagnostic detailDiag = diags.fragment("inapplicable.method",
3447                         Kinds.kindName(c.sym),
3448                         c.sym.location(site, types),
3449                         c.sym.asMemberOf(site, types),
3450                         c.details);
3451                 details.put(c.sym, detailDiag);
3452             }
3453             return List.from(details.values());
3454         }
3455     }
3456 
3457     /**
3458      * An InvalidSymbolError error class indicating that a symbol is not
3459      * accessible from a given site
3460      */
3461     class AccessError extends InvalidSymbolError {
3462 
3463         private Env<AttrContext> env;
3464         private Type site;
3465 
3466         AccessError(Symbol sym) {
3467             this(null, null, sym);
3468         }
3469 
3470         AccessError(Env<AttrContext> env, Type site, Symbol sym) {
3471             super(HIDDEN, sym, "access error");
3472             this.env = env;
3473             this.site = site;
3474             if (debugResolve)
3475                 log.error("proc.messager", sym + " @ " + site + " is inaccessible.");
3476         }
3477 
3478         @Override
3479         public boolean exists() {
3480             return false;
3481         }
3482 
3483         @Override
3484         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3485                 DiagnosticPosition pos,
3486                 Symbol location,
3487                 Type site,
3488                 Name name,
3489                 List<Type> argtypes,
3490                 List<Type> typeargtypes) {
3491             if (sym.owner.type.hasTag(ERROR))
3492                 return null;
3493 
3494             if (sym.name == names.init && sym.owner != site.tsym) {
3495                 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind,
3496                         pos, location, site, name, argtypes, typeargtypes);
3497             }
3498             else if ((sym.flags() & PUBLIC) != 0
3499                 || (env != null && this.site != null
3500                     && !isAccessible(env, this.site))) {
3501                 return diags.create(dkind, log.currentSource(),
3502                         pos, "not.def.access.class.intf.cant.access",
3503                     sym, sym.location());
3504             }
3505             else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) {
3506                 return diags.create(dkind, log.currentSource(),
3507                         pos, "report.access", sym,
3508                         asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
3509                         sym.location());
3510             }
3511             else {
3512                 return diags.create(dkind, log.currentSource(),
3513                         pos, "not.def.public.cant.access", sym, sym.location());
3514             }
3515         }
3516     }
3517 
3518     /**
3519      * InvalidSymbolError error class indicating that an instance member
3520      * has erroneously been accessed from a static context.
3521      */
3522     class StaticError extends InvalidSymbolError {
3523 
3524         StaticError(Symbol sym) {
3525             super(STATICERR, sym, "static error");
3526         }
3527 
3528         @Override
3529         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3530                 DiagnosticPosition pos,
3531                 Symbol location,
3532                 Type site,
3533                 Name name,
3534                 List<Type> argtypes,
3535                 List<Type> typeargtypes) {
3536             Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS))
3537                 ? types.erasure(sym.type).tsym
3538                 : sym);
3539             return diags.create(dkind, log.currentSource(), pos,
3540                     "non-static.cant.be.ref", kindName(sym), errSym);
3541         }
3542     }
3543 
3544     /**
3545      * InvalidSymbolError error class indicating that a pair of symbols
3546      * (either methods, constructors or operands) are ambiguous
3547      * given an actual arguments/type argument list.
3548      */
3549     class AmbiguityError extends ResolveError {
3550 
3551         /** The other maximally specific symbol */
3552         List<Symbol> ambiguousSyms = List.nil();
3553 
3554         @Override
3555         public boolean exists() {
3556             return true;
3557         }
3558 
3559         AmbiguityError(Symbol sym1, Symbol sym2) {
3560             super(AMBIGUOUS, "ambiguity error");
3561             ambiguousSyms = flatten(sym2).appendList(flatten(sym1));
3562         }
3563 
3564         private List<Symbol> flatten(Symbol sym) {
3565             if (sym.kind == AMBIGUOUS) {
3566                 return ((AmbiguityError)sym).ambiguousSyms;
3567             } else {
3568                 return List.of(sym);
3569             }
3570         }
3571 
3572         AmbiguityError addAmbiguousSymbol(Symbol s) {
3573             ambiguousSyms = ambiguousSyms.prepend(s);
3574             return this;
3575         }
3576 
3577         @Override
3578         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3579                 DiagnosticPosition pos,
3580                 Symbol location,
3581                 Type site,
3582                 Name name,
3583                 List<Type> argtypes,
3584                 List<Type> typeargtypes) {
3585             List<Symbol> diagSyms = ambiguousSyms.reverse();
3586             Symbol s1 = diagSyms.head;
3587             Symbol s2 = diagSyms.tail.head;
3588             Name sname = s1.name;
3589             if (sname == names.init) sname = s1.owner.name;
3590             return diags.create(dkind, log.currentSource(),
3591                       pos, "ref.ambiguous", sname,
3592                       kindName(s1),
3593                       s1,
3594                       s1.location(site, types),
3595                       kindName(s2),
3596                       s2,
3597                       s2.location(site, types));
3598         }
3599 
3600         /**
3601          * If multiple applicable methods are found during overload and none of them
3602          * is more specific than the others, attempt to merge their signatures.
3603          */
3604         Symbol mergeAbstracts(Type site) {
3605             Symbol fst = ambiguousSyms.last();
3606             Symbol res = fst;
3607             for (Symbol s : ambiguousSyms.reverse()) {
3608                 Type mt1 = types.memberType(site, res);
3609                 Type mt2 = types.memberType(site, s);
3610                 if ((s.flags() & ABSTRACT) == 0 ||
3611                         !types.overrideEquivalent(mt1, mt2) ||
3612                         !types.isSameTypes(fst.erasure(types).getParameterTypes(),
3613                                        s.erasure(types).getParameterTypes())) {
3614                     //ambiguity cannot be resolved
3615                     return this;
3616                 } else {
3617                     Type mst = mostSpecificReturnType(mt1, mt2);
3618                     if (mst == null) {
3619                         // Theoretically, this can't happen, but it is possible
3620                         // due to error recovery or mixing incompatible class files
3621                         return this;
3622                     }
3623                     Symbol mostSpecific = mst == mt1 ? res : s;
3624                     List<Type> allThrown = chk.intersect(mt1.getThrownTypes(), mt2.getThrownTypes());
3625                     Type newSig = types.createMethodTypeWithThrown(mostSpecific.type, allThrown);
3626                     res = new MethodSymbol(
3627                             mostSpecific.flags(),
3628                             mostSpecific.name,
3629                             newSig,
3630                             mostSpecific.owner);
3631                 }
3632             }
3633             return res;
3634         }
3635 
3636         @Override
3637         protected Symbol access(Name name, TypeSymbol location) {
3638             Symbol firstAmbiguity = ambiguousSyms.last();
3639             return firstAmbiguity.kind == TYP ?
3640                     types.createErrorType(name, location, firstAmbiguity.type).tsym :
3641                     firstAmbiguity;
3642         }
3643     }
3644 
3645     class BadVarargsMethod extends ResolveError {
3646 
3647         ResolveError delegatedError;
3648 
3649         BadVarargsMethod(ResolveError delegatedError) {
3650             super(delegatedError.kind, "badVarargs");
3651             this.delegatedError = delegatedError;
3652         }
3653 
3654         @Override
3655         public Symbol baseSymbol() {
3656             return delegatedError.baseSymbol();
3657         }
3658 
3659         @Override
3660         protected Symbol access(Name name, TypeSymbol location) {
3661             return delegatedError.access(name, location);
3662         }
3663 
3664         @Override
3665         public boolean exists() {
3666             return true;
3667         }
3668 
3669         @Override
3670         JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
3671             return delegatedError.getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes);
3672         }
3673     }
3674 
3675     enum MethodResolutionPhase {
3676         BASIC(false, false),
3677         BOX(true, false),
3678         VARARITY(true, true) {
3679             @Override
3680             public Symbol mergeResults(Symbol bestSoFar, Symbol sym) {
3681                 switch (sym.kind) {
3682                     case WRONG_MTH:
3683                         return (bestSoFar.kind == WRONG_MTH || bestSoFar.kind == WRONG_MTHS) ?
3684                             bestSoFar :
3685                             sym;
3686                     case ABSENT_MTH:
3687                         return bestSoFar;
3688                     default:
3689                         return sym;
3690                 }
3691             }
3692         };
3693 
3694         final boolean isBoxingRequired;
3695         final boolean isVarargsRequired;
3696 
3697         MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) {
3698            this.isBoxingRequired = isBoxingRequired;
3699            this.isVarargsRequired = isVarargsRequired;
3700         }
3701 
3702         public boolean isBoxingRequired() {
3703             return isBoxingRequired;
3704         }
3705 
3706         public boolean isVarargsRequired() {
3707             return isVarargsRequired;
3708         }
3709 
3710         public boolean isApplicable(boolean boxingEnabled, boolean varargsEnabled) {
3711             return (varargsEnabled || !isVarargsRequired) &&
3712                    (boxingEnabled || !isBoxingRequired);
3713         }
3714 
3715         public Symbol mergeResults(Symbol prev, Symbol sym) {
3716             return sym;
3717         }
3718     }
3719 
3720     final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
3721 
3722     /**
3723      * A resolution context is used to keep track of intermediate results of
3724      * overload resolution, such as list of method that are not applicable
3725      * (used to generate more precise diagnostics) and so on. Resolution contexts
3726      * can be nested - this means that when each overload resolution routine should
3727      * work within the resolution context it created.
3728      */
3729     class MethodResolutionContext {
3730 
3731         private List<Candidate> candidates = List.nil();
3732 
3733         MethodResolutionPhase step = null;
3734 
3735         MethodCheck methodCheck = resolveMethodCheck;
3736 
3737         private boolean internalResolution = false;
3738         private DeferredAttr.AttrMode attrMode = DeferredAttr.AttrMode.SPECULATIVE;
3739 
3740         void addInapplicableCandidate(Symbol sym, JCDiagnostic details) {
3741             Candidate c = new Candidate(currentResolutionContext.step, sym, details, null);
3742             candidates = candidates.append(c);
3743         }
3744 
3745         void addApplicableCandidate(Symbol sym, Type mtype) {
3746             Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype);
3747             candidates = candidates.append(c);
3748         }
3749 
3750         DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext, ResultInfo pendingResult, Warner warn) {
3751             return deferredAttr.new DeferredAttrContext(attrMode, sym, step, inferenceContext, pendingResult != null ? pendingResult.checkContext.deferredAttrContext() : deferredAttr.emptyDeferredAttrContext, warn);
3752         }
3753 
3754         /**
3755          * This class represents an overload resolution candidate. There are two
3756          * kinds of candidates: applicable methods and inapplicable methods;
3757          * applicable methods have a pointer to the instantiated method type,
3758          * while inapplicable candidates contain further details about the
3759          * reason why the method has been considered inapplicable.
3760          */
3761         @SuppressWarnings("overrides")
3762         class Candidate {
3763 
3764             final MethodResolutionPhase step;
3765             final Symbol sym;
3766             final JCDiagnostic details;
3767             final Type mtype;
3768 
3769             private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
3770                 this.step = step;
3771                 this.sym = sym;
3772                 this.details = details;
3773                 this.mtype = mtype;
3774             }
3775 
3776             @Override
3777             public boolean equals(Object o) {
3778                 if (o instanceof Candidate) {
3779                     Symbol s1 = this.sym;
3780                     Symbol s2 = ((Candidate)o).sym;
3781                     if  ((s1 != s2 &&
3782                             (s1.overrides(s2, s1.owner.type.tsym, types, false) ||
3783                             (s2.overrides(s1, s2.owner.type.tsym, types, false)))) ||
3784                             ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner))
3785                         return true;
3786                 }
3787                 return false;
3788             }
3789 
3790             boolean isApplicable() {
3791                 return mtype != null;
3792             }
3793         }
3794 
3795         DeferredAttr.AttrMode attrMode() {
3796             return attrMode;
3797         }
3798 
3799         boolean internal() {
3800             return internalResolution;
3801         }
3802     }
3803 
3804     MethodResolutionContext currentResolutionContext = null;
3805 }