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     /** Find qualified member type.
1788      *  @param env       The current environment.
1789      *  @param site      The original type from where the selection takes
1790      *                   place.
1791      *  @param name      The type's name.
1792      *  @param c         The class to search for the member type. This is
1793      *                   always a superclass or implemented interface of
1794      *                   site's class.
1795      */
1796     Symbol findMemberType(Env<AttrContext> env,
1797                           Type site,
1798                           Name name,
1799                           TypeSymbol c) {
1800         Symbol bestSoFar = typeNotFound;
1801         Symbol sym;
1802         Scope.Entry e = c.members().lookup(name);
1803         while (e.scope != null) {
1804             if (e.sym.kind == TYP) {
1805                 return isAccessible(env, site, e.sym)
1806                     ? e.sym
1807                     : new AccessError(env, site, e.sym);
1808             }
1809             e = e.next();
1810         }
1811         Type st = types.supertype(c.type);
1812         if (st != null && st.hasTag(CLASS)) {
1813             sym = findMemberType(env, site, name, st.tsym);
1814             if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1815         }
1816         for (List<Type> l = types.interfaces(c.type);
1817              bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
1818              l = l.tail) {
1819             sym = findMemberType(env, site, name, l.head.tsym);
1820             if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&
1821                 sym.owner != bestSoFar.owner)
1822                 bestSoFar = new AmbiguityError(bestSoFar, sym);
1823             else if (sym.kind < bestSoFar.kind)
1824                 bestSoFar = sym;
1825         }
1826         return bestSoFar;
1827     }
1828 
1829     /** Find a global type in given scope and load corresponding class.
1830      *  @param env       The current environment.
1831      *  @param scope     The scope in which to look for the type.
1832      *  @param name      The type's name.
1833      */
1834     Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {
1835         Symbol bestSoFar = typeNotFound;
1836         for (Scope.Entry e = scope.lookup(name); e.scope != null; e = e.next()) {
1837             Symbol sym = loadClass(env, e.sym.flatName());
1838             if (bestSoFar.kind == TYP && sym.kind == TYP &&
1839                 bestSoFar != sym)
1840                 return new AmbiguityError(bestSoFar, sym);
1841             else if (sym.kind < bestSoFar.kind)
1842                 bestSoFar = sym;
1843         }
1844         return bestSoFar;
1845     }
1846 
1847     /** Find an unqualified type symbol.
1848      *  @param env       The current environment.
1849      *  @param name      The type's name.
1850      */
1851     Symbol findType(Env<AttrContext> env, Name name) {
1852         Symbol bestSoFar = typeNotFound;
1853         Symbol sym;
1854         boolean staticOnly = false;
1855         Symbol staticError = null;
1856         for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {
1857             if (isStatic(env1)) staticOnly = true;
1858             for (Scope.Entry e = env1.info.scope.lookup(name);
1859                  e.scope != null;
1860                  e = e.next()) {
1861                 if (e.sym.kind == TYP) {
1862                     if (staticOnly &&
1863                         e.sym.type.hasTag(TYPEVAR) &&
1864                         e.sym.owner.kind == TYP) staticError = e.sym;
1865                     else
1866                         return e.sym;
1867                 }
1868             }
1869 
1870             sym = findMemberType(env1, env1.enclClass.sym.type, name,
1871                                  env1.enclClass.sym);
1872             if (staticOnly && sym.kind == TYP &&
1873                 sym.type.hasTag(CLASS) &&
1874                 sym.type.getEnclosingType().hasTag(CLASS) &&
1875                 env1.enclClass.sym.type.isParameterized() &&
1876                 sym.type.getEnclosingType().isParameterized())
1877                 return new StaticError(sym);
1878             else if (sym.exists()) return sym;
1879             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1880 
1881             JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass;
1882             if ((encl.sym.flags() & STATIC) != 0)
1883                 staticOnly = true;
1884         }
1885         if (staticError != null)
1886             return new StaticError(staticError);
1887 
1888         if (!env.tree.hasTag(IMPORT)) {
1889             sym = findGlobalType(env, env.toplevel.namedImportScope, name);
1890             if (sym.exists()) return sym;
1891             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1892 
1893             sym = findGlobalType(env, env.toplevel.packge.members(), name);
1894             if (sym.exists()) return sym;
1895             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1896 
1897             sym = findGlobalType(env, env.toplevel.starImportScope, name);
1898             if (sym.exists()) return sym;
1899             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1900         }
1901 
1902         return bestSoFar;
1903     }
1904 
1905     /** Find an unqualified identifier which matches a specified kind set.
1906      *  @param env       The current environment.
1907      *  @param name      The identifier's name.
1908      *  @param kind      Indicates the possible symbol kinds
1909      *                   (a subset of VAL, TYP, PCK).
1910      */
1911     Symbol findIdent(Env<AttrContext> env, Name name, int kind) {
1912         Symbol bestSoFar = typeNotFound;
1913         Symbol sym;
1914 
1915         if ((kind & VAR) != 0) {
1916             sym = findVar(env, name);
1917             if (sym.exists()) return sym;
1918             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1919         }
1920 
1921         if ((kind & TYP) != 0) {
1922             sym = findType(env, name);
1923             if (sym.kind==TYP) {
1924                  reportDependence(env.enclClass.sym, sym);
1925             }
1926             if (sym.exists()) return sym;
1927             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1928         }
1929 
1930         if ((kind & PCK) != 0) return reader.enterPackage(name);
1931         else return bestSoFar;
1932     }
1933 
1934     /** Report dependencies.
1935      * @param from The enclosing class sym
1936      * @param to   The found identifier that the class depends on.
1937      */
1938     public void reportDependence(Symbol from, Symbol to) {
1939         // Override if you want to collect the reported dependencies.
1940     }
1941 
1942     /** Find an identifier in a package which matches a specified kind set.
1943      *  @param env       The current environment.
1944      *  @param name      The identifier's name.
1945      *  @param kind      Indicates the possible symbol kinds
1946      *                   (a nonempty subset of TYP, PCK).
1947      */
1948     Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck,
1949                               Name name, int kind) {
1950         Name fullname = TypeSymbol.formFullName(name, pck);
1951         Symbol bestSoFar = typeNotFound;
1952         PackageSymbol pack = null;
1953         if ((kind & PCK) != 0) {
1954             pack = reader.enterPackage(fullname);
1955             if (pack.exists()) return pack;
1956         }
1957         if ((kind & TYP) != 0) {
1958             Symbol sym = loadClass(env, fullname);
1959             if (sym.exists()) {
1960                 // don't allow programs to use flatnames
1961                 if (name == sym.name) return sym;
1962             }
1963             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1964         }
1965         return (pack != null) ? pack : bestSoFar;
1966     }
1967 
1968     /** Find an identifier among the members of a given type `site'.
1969      *  @param env       The current environment.
1970      *  @param site      The type containing the symbol to be found.
1971      *  @param name      The identifier's name.
1972      *  @param kind      Indicates the possible symbol kinds
1973      *                   (a subset of VAL, TYP).
1974      */
1975     Symbol findIdentInType(Env<AttrContext> env, Type site,
1976                            Name name, int kind) {
1977         Symbol bestSoFar = typeNotFound;
1978         Symbol sym;
1979         if ((kind & VAR) != 0) {
1980             sym = findField(env, site, name, site.tsym);
1981             if (sym.exists()) return sym;
1982             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1983         }
1984 
1985         if ((kind & TYP) != 0) {
1986             sym = findMemberType(env, site, name, site.tsym);
1987             if (sym.exists()) return sym;
1988             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1989         }
1990         return bestSoFar;
1991     }
1992 
1993 /* ***************************************************************************
1994  *  Access checking
1995  *  The following methods convert ResolveErrors to ErrorSymbols, issuing
1996  *  an error message in the process
1997  ****************************************************************************/
1998 
1999     /** If `sym' is a bad symbol: report error and return errSymbol
2000      *  else pass through unchanged,
2001      *  additional arguments duplicate what has been used in trying to find the
2002      *  symbol {@literal (--> flyweight pattern)}. This improves performance since we
2003      *  expect misses to happen frequently.
2004      *
2005      *  @param sym       The symbol that was found, or a ResolveError.
2006      *  @param pos       The position to use for error reporting.
2007      *  @param location  The symbol the served as a context for this lookup
2008      *  @param site      The original type from where the selection took place.
2009      *  @param name      The symbol's name.
2010      *  @param qualified Did we get here through a qualified expression resolution?
2011      *  @param argtypes  The invocation's value arguments,
2012      *                   if we looked for a method.
2013      *  @param typeargtypes  The invocation's type arguments,
2014      *                   if we looked for a method.
2015      *  @param logResolveHelper helper class used to log resolve errors
2016      */
2017     Symbol accessInternal(Symbol sym,
2018                   DiagnosticPosition pos,
2019                   Symbol location,
2020                   Type site,
2021                   Name name,
2022                   boolean qualified,
2023                   List<Type> argtypes,
2024                   List<Type> typeargtypes,
2025                   LogResolveHelper logResolveHelper) {
2026         if (sym.kind >= AMBIGUOUS) {
2027             ResolveError errSym = (ResolveError)sym;
2028             sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol);
2029             argtypes = logResolveHelper.getArgumentTypes(errSym, sym, name, argtypes);
2030             if (logResolveHelper.resolveDiagnosticNeeded(site, argtypes, typeargtypes)) {
2031                 logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes);
2032             }
2033         }
2034         return sym;
2035     }
2036 
2037     /**
2038      * Variant of the generalized access routine, to be used for generating method
2039      * resolution diagnostics
2040      */
2041     Symbol accessMethod(Symbol sym,
2042                   DiagnosticPosition pos,
2043                   Symbol location,
2044                   Type site,
2045                   Name name,
2046                   boolean qualified,
2047                   List<Type> argtypes,
2048                   List<Type> typeargtypes) {
2049         return accessInternal(sym, pos, location, site, name, qualified, argtypes, typeargtypes, methodLogResolveHelper);
2050     }
2051 
2052     /** Same as original accessMethod(), but without location.
2053      */
2054     Symbol accessMethod(Symbol sym,
2055                   DiagnosticPosition pos,
2056                   Type site,
2057                   Name name,
2058                   boolean qualified,
2059                   List<Type> argtypes,
2060                   List<Type> typeargtypes) {
2061         return accessMethod(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes);
2062     }
2063 
2064     /**
2065      * Variant of the generalized access routine, to be used for generating variable,
2066      * type resolution diagnostics
2067      */
2068     Symbol accessBase(Symbol sym,
2069                   DiagnosticPosition pos,
2070                   Symbol location,
2071                   Type site,
2072                   Name name,
2073                   boolean qualified) {
2074         return accessInternal(sym, pos, location, site, name, qualified, List.<Type>nil(), null, basicLogResolveHelper);
2075     }
2076 
2077     /** Same as original accessBase(), but without location.
2078      */
2079     Symbol accessBase(Symbol sym,
2080                   DiagnosticPosition pos,
2081                   Type site,
2082                   Name name,
2083                   boolean qualified) {
2084         return accessBase(sym, pos, site.tsym, site, name, qualified);
2085     }
2086 
2087     interface LogResolveHelper {
2088         boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes);
2089         List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes);
2090     }
2091 
2092     LogResolveHelper basicLogResolveHelper = new LogResolveHelper() {
2093         public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2094             return !site.isErroneous();
2095         }
2096         public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2097             return argtypes;
2098         }
2099     };
2100 
2101     LogResolveHelper methodLogResolveHelper = new LogResolveHelper() {
2102         public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2103             return !site.isErroneous() &&
2104                         !Type.isErroneous(argtypes) &&
2105                         (typeargtypes == null || !Type.isErroneous(typeargtypes));
2106         }
2107         public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2108             return (syms.operatorNames.contains(name)) ?
2109                     argtypes :
2110                     Type.map(argtypes, new ResolveDeferredRecoveryMap(accessedSym));
2111         }
2112 
2113         class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap {
2114 
2115             public ResolveDeferredRecoveryMap(Symbol msym) {
2116                 deferredAttr.super(AttrMode.SPECULATIVE, msym, currentResolutionContext.step);
2117             }
2118 
2119             @Override
2120             protected Type typeOf(DeferredType dt) {
2121                 Type res = super.typeOf(dt);
2122                 if (!res.isErroneous()) {
2123                     switch (TreeInfo.skipParens(dt.tree).getTag()) {
2124                         case LAMBDA:
2125                         case REFERENCE:
2126                             return dt;
2127                         case CONDEXPR:
2128                             return res == Type.recoveryType ?
2129                                     dt : res;
2130                     }
2131                 }
2132                 return res;
2133             }
2134         }
2135     };
2136 
2137     /** Check that sym is not an abstract method.
2138      */
2139     void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
2140         if ((sym.flags() & ABSTRACT) != 0 && (sym.flags() & DEFAULT) == 0)
2141             log.error(pos, "abstract.cant.be.accessed.directly",
2142                       kindName(sym), sym, sym.location());
2143     }
2144 
2145 /* ***************************************************************************
2146  *  Debugging
2147  ****************************************************************************/
2148 
2149     /** print all scopes starting with scope s and proceeding outwards.
2150      *  used for debugging.
2151      */
2152     public void printscopes(Scope s) {
2153         while (s != null) {
2154             if (s.owner != null)
2155                 System.err.print(s.owner + ": ");
2156             for (Scope.Entry e = s.elems; e != null; e = e.sibling) {
2157                 if ((e.sym.flags() & ABSTRACT) != 0)
2158                     System.err.print("abstract ");
2159                 System.err.print(e.sym + " ");
2160             }
2161             System.err.println();
2162             s = s.next;
2163         }
2164     }
2165 
2166     void printscopes(Env<AttrContext> env) {
2167         while (env.outer != null) {
2168             System.err.println("------------------------------");
2169             printscopes(env.info.scope);
2170             env = env.outer;
2171         }
2172     }
2173 
2174     public void printscopes(Type t) {
2175         while (t.hasTag(CLASS)) {
2176             printscopes(t.tsym.members());
2177             t = types.supertype(t);
2178         }
2179     }
2180 
2181 /* ***************************************************************************
2182  *  Name resolution
2183  *  Naming conventions are as for symbol lookup
2184  *  Unlike the find... methods these methods will report access errors
2185  ****************************************************************************/
2186 
2187     /** Resolve an unqualified (non-method) identifier.
2188      *  @param pos       The position to use for error reporting.
2189      *  @param env       The environment current at the identifier use.
2190      *  @param name      The identifier's name.
2191      *  @param kind      The set of admissible symbol kinds for the identifier.
2192      */
2193     Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,
2194                         Name name, int kind) {
2195         return accessBase(
2196             findIdent(env, name, kind),
2197             pos, env.enclClass.sym.type, name, false);
2198     }
2199 
2200     /** Resolve an unqualified method identifier.
2201      *  @param pos       The position to use for error reporting.
2202      *  @param env       The environment current at the method invocation.
2203      *  @param name      The identifier's name.
2204      *  @param argtypes  The types of the invocation's value arguments.
2205      *  @param typeargtypes  The types of the invocation's type arguments.
2206      */
2207     Symbol resolveMethod(DiagnosticPosition pos,
2208                          Env<AttrContext> env,
2209                          Name name,
2210                          List<Type> argtypes,
2211                          List<Type> typeargtypes) {
2212         return lookupMethod(env, pos, env.enclClass.sym, resolveMethodCheck,
2213                 new BasicLookupHelper(name, env.enclClass.sym.type, argtypes, typeargtypes) {
2214                     @Override
2215                     Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2216                         return findFun(env, name, argtypes, typeargtypes,
2217                                 phase.isBoxingRequired(),
2218                                 phase.isVarargsRequired());
2219                     }});
2220     }
2221 
2222     /** Resolve a qualified method identifier
2223      *  @param pos       The position to use for error reporting.
2224      *  @param env       The environment current at the method invocation.
2225      *  @param site      The type of the qualifying expression, in which
2226      *                   identifier is searched.
2227      *  @param name      The identifier's name.
2228      *  @param argtypes  The types of the invocation's value arguments.
2229      *  @param typeargtypes  The types of the invocation's type arguments.
2230      */
2231     Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
2232                                   Type site, Name name, List<Type> argtypes,
2233                                   List<Type> typeargtypes) {
2234         return resolveQualifiedMethod(pos, env, site.tsym, site, name, argtypes, typeargtypes);
2235     }
2236     Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
2237                                   Symbol location, Type site, Name name, List<Type> argtypes,
2238                                   List<Type> typeargtypes) {
2239         return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes);
2240     }
2241     private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext,
2242                                   DiagnosticPosition pos, Env<AttrContext> env,
2243                                   Symbol location, Type site, Name name, List<Type> argtypes,
2244                                   List<Type> typeargtypes) {
2245         return lookupMethod(env, pos, location, resolveContext, new BasicLookupHelper(name, site, argtypes, typeargtypes) {
2246             @Override
2247             Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2248                 return findMethod(env, site, name, argtypes, typeargtypes,
2249                         phase.isBoxingRequired(),
2250                         phase.isVarargsRequired(), false);
2251             }
2252             @Override
2253             Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2254                 if (sym.kind >= AMBIGUOUS) {
2255                     sym = super.access(env, pos, location, sym);
2256                 } else if (allowMethodHandles) {
2257                     MethodSymbol msym = (MethodSymbol)sym;
2258                     if (msym.isSignaturePolymorphic(types)) {
2259                         return findPolymorphicSignatureInstance(env, sym, argtypes);
2260                     }
2261                 }
2262                 return sym;
2263             }
2264         });
2265     }
2266 
2267     /** Find or create an implicit method of exactly the given type (after erasure).
2268      *  Searches in a side table, not the main scope of the site.
2269      *  This emulates the lookup process required by JSR 292 in JVM.
2270      *  @param env       Attribution environment
2271      *  @param spMethod  signature polymorphic method - i.e. MH.invokeExact
2272      *  @param argtypes  The required argument types
2273      */
2274     Symbol findPolymorphicSignatureInstance(Env<AttrContext> env,
2275                                             final Symbol spMethod,
2276                                             List<Type> argtypes) {
2277         Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
2278                 (MethodSymbol)spMethod, currentResolutionContext, argtypes);
2279         for (Symbol sym : polymorphicSignatureScope.getElementsByName(spMethod.name)) {
2280             if (types.isSameType(mtype, sym.type)) {
2281                return sym;
2282             }
2283         }
2284 
2285         // create the desired method
2286         long flags = ABSTRACT | HYPOTHETICAL | spMethod.flags() & Flags.AccessFlags;
2287         Symbol msym = new MethodSymbol(flags, spMethod.name, mtype, spMethod.owner) {
2288             @Override
2289             public Symbol baseSymbol() {
2290                 return spMethod;
2291             }
2292         };
2293         polymorphicSignatureScope.enter(msym);
2294         return msym;
2295     }
2296 
2297     /** Resolve a qualified method identifier, throw a fatal error if not
2298      *  found.
2299      *  @param pos       The position to use for error reporting.
2300      *  @param env       The environment current at the method invocation.
2301      *  @param site      The type of the qualifying expression, in which
2302      *                   identifier is searched.
2303      *  @param name      The identifier's name.
2304      *  @param argtypes  The types of the invocation's value arguments.
2305      *  @param typeargtypes  The types of the invocation's type arguments.
2306      */
2307     public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env,
2308                                         Type site, Name name,
2309                                         List<Type> argtypes,
2310                                         List<Type> typeargtypes) {
2311         MethodResolutionContext resolveContext = new MethodResolutionContext();
2312         resolveContext.internalResolution = true;
2313         Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym,
2314                 site, name, argtypes, typeargtypes);
2315         if (sym.kind == MTH) return (MethodSymbol)sym;
2316         else throw new FatalError(
2317                  diags.fragment("fatal.err.cant.locate.meth",
2318                                 name));
2319     }
2320 
2321     /** Resolve constructor.
2322      *  @param pos       The position to use for error reporting.
2323      *  @param env       The environment current at the constructor invocation.
2324      *  @param site      The type of class for which a constructor is searched.
2325      *  @param argtypes  The types of the constructor invocation's value
2326      *                   arguments.
2327      *  @param typeargtypes  The types of the constructor invocation's type
2328      *                   arguments.
2329      */
2330     Symbol resolveConstructor(DiagnosticPosition pos,
2331                               Env<AttrContext> env,
2332                               Type site,
2333                               List<Type> argtypes,
2334                               List<Type> typeargtypes) {
2335         return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes);
2336     }
2337 
2338     private Symbol resolveConstructor(MethodResolutionContext resolveContext,
2339                               final DiagnosticPosition pos,
2340                               Env<AttrContext> env,
2341                               Type site,
2342                               List<Type> argtypes,
2343                               List<Type> typeargtypes) {
2344         return lookupMethod(env, pos, site.tsym, resolveContext, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2345             @Override
2346             Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2347                 return findConstructor(pos, env, site, argtypes, typeargtypes,
2348                         phase.isBoxingRequired(),
2349                         phase.isVarargsRequired());
2350             }
2351         });
2352     }
2353 
2354     /** Resolve a constructor, throw a fatal error if not found.
2355      *  @param pos       The position to use for error reporting.
2356      *  @param env       The environment current at the method invocation.
2357      *  @param site      The type to be constructed.
2358      *  @param argtypes  The types of the invocation's value arguments.
2359      *  @param typeargtypes  The types of the invocation's type arguments.
2360      */
2361     public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2362                                         Type site,
2363                                         List<Type> argtypes,
2364                                         List<Type> typeargtypes) {
2365         MethodResolutionContext resolveContext = new MethodResolutionContext();
2366         resolveContext.internalResolution = true;
2367         Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
2368         if (sym.kind == MTH) return (MethodSymbol)sym;
2369         else throw new FatalError(
2370                  diags.fragment("fatal.err.cant.locate.ctor", site));
2371     }
2372 
2373     Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2374                               Type site, List<Type> argtypes,
2375                               List<Type> typeargtypes,
2376                               boolean allowBoxing,
2377                               boolean useVarargs) {
2378         Symbol sym = findMethod(env, site,
2379                                     names.init, argtypes,
2380                                     typeargtypes, allowBoxing,
2381                                     useVarargs, false);
2382         chk.checkDeprecated(pos, env.info.scope.owner, sym);
2383         return sym;
2384     }
2385 
2386     /** Resolve constructor using diamond inference.
2387      *  @param pos       The position to use for error reporting.
2388      *  @param env       The environment current at the constructor invocation.
2389      *  @param site      The type of class for which a constructor is searched.
2390      *                   The scope of this class has been touched in attribution.
2391      *  @param argtypes  The types of the constructor invocation's value
2392      *                   arguments.
2393      *  @param typeargtypes  The types of the constructor invocation's type
2394      *                   arguments.
2395      */
2396     Symbol resolveDiamond(DiagnosticPosition pos,
2397                               Env<AttrContext> env,
2398                               Type site,
2399                               List<Type> argtypes,
2400                               List<Type> typeargtypes) {
2401         return lookupMethod(env, pos, site.tsym, resolveMethodCheck,
2402                 new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2403                     @Override
2404                     Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2405                         return findDiamond(env, site, argtypes, typeargtypes,
2406                                 phase.isBoxingRequired(),
2407                                 phase.isVarargsRequired());
2408                     }
2409                     @Override
2410                     Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2411                         if (sym.kind >= AMBIGUOUS) {
2412                             final JCDiagnostic details = sym.kind == WRONG_MTH ?
2413                                             ((InapplicableSymbolError)sym).errCandidate().details :
2414                                             null;
2415                             sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) {
2416                                 @Override
2417                                 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
2418                                         Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
2419                                     String key = details == null ?
2420                                         "cant.apply.diamond" :
2421                                         "cant.apply.diamond.1";
2422                                     return diags.create(dkind, log.currentSource(), pos, key,
2423                                             diags.fragment("diamond", site.tsym), details);
2424                                 }
2425                             };
2426                             sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
2427                             env.info.pendingResolutionPhase = currentResolutionContext.step;
2428                         }
2429                         return sym;
2430                     }});
2431     }
2432 
2433     /** This method scans all the constructor symbol in a given class scope -
2434      *  assuming that the original scope contains a constructor of the kind:
2435      *  {@code Foo(X x, Y y)}, where X,Y are class type-variables declared in Foo,
2436      *  a method check is executed against the modified constructor type:
2437      *  {@code <X,Y>Foo<X,Y>(X x, Y y)}. This is crucial in order to enable diamond
2438      *  inference. The inferred return type of the synthetic constructor IS
2439      *  the inferred type for the diamond operator.
2440      */
2441     private Symbol findDiamond(Env<AttrContext> env,
2442                               Type site,
2443                               List<Type> argtypes,
2444                               List<Type> typeargtypes,
2445                               boolean allowBoxing,
2446                               boolean useVarargs) {
2447         Symbol bestSoFar = methodNotFound;
2448         for (Scope.Entry e = site.tsym.members().lookup(names.init);
2449              e.scope != null;
2450              e = e.next()) {
2451             final Symbol sym = e.sym;
2452             //- System.out.println(" e " + e.sym);
2453             if (sym.kind == MTH &&
2454                 (sym.flags_field & SYNTHETIC) == 0) {
2455                     List<Type> oldParams = e.sym.type.hasTag(FORALL) ?
2456                             ((ForAll)sym.type).tvars :
2457                             List.<Type>nil();
2458                     Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
2459                             types.createMethodTypeWithReturn(sym.type.asMethodType(), site));
2460                     MethodSymbol newConstr = new MethodSymbol(sym.flags(), names.init, constrType, site.tsym) {
2461                         @Override
2462                         public Symbol baseSymbol() {
2463                             return sym;
2464                         }
2465                     };
2466                     bestSoFar = selectBest(env, site, argtypes, typeargtypes,
2467                             newConstr,
2468                             bestSoFar,
2469                             allowBoxing,
2470                             useVarargs,
2471                             false);
2472             }
2473         }
2474         return bestSoFar;
2475     }
2476 
2477 
2478 
2479     /** Resolve operator.
2480      *  @param pos       The position to use for error reporting.
2481      *  @param optag     The tag of the operation tree.
2482      *  @param env       The environment current at the operation.
2483      *  @param argtypes  The types of the operands.
2484      */
2485     Symbol resolveOperator(DiagnosticPosition pos, JCTree.Tag optag,
2486                            Env<AttrContext> env, List<Type> argtypes) {
2487         MethodResolutionContext prevResolutionContext = currentResolutionContext;
2488         try {
2489             currentResolutionContext = new MethodResolutionContext();
2490             Name name = treeinfo.operatorName(optag);
2491             env.info.pendingResolutionPhase = currentResolutionContext.step = BASIC;
2492             Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
2493                                     null, false, false, true);
2494             if (boxingEnabled && sym.kind >= WRONG_MTHS)
2495                 env.info.pendingResolutionPhase = currentResolutionContext.step = BOX;
2496                 sym = findMethod(env, syms.predefClass.type, name, argtypes,
2497                                  null, true, false, true);
2498             return accessMethod(sym, pos, env.enclClass.sym.type, name,
2499                           false, argtypes, null);
2500         }
2501         finally {
2502             currentResolutionContext = prevResolutionContext;
2503         }
2504     }
2505 
2506     /** Resolve operator.
2507      *  @param pos       The position to use for error reporting.
2508      *  @param optag     The tag of the operation tree.
2509      *  @param env       The environment current at the operation.
2510      *  @param arg       The type of the operand.
2511      */
2512     Symbol resolveUnaryOperator(DiagnosticPosition pos, JCTree.Tag optag, Env<AttrContext> env, Type arg) {
2513         return resolveOperator(pos, optag, env, List.of(arg));
2514     }
2515 
2516     /** Resolve binary operator.
2517      *  @param pos       The position to use for error reporting.
2518      *  @param optag     The tag of the operation tree.
2519      *  @param env       The environment current at the operation.
2520      *  @param left      The types of the left operand.
2521      *  @param right     The types of the right operand.
2522      */
2523     Symbol resolveBinaryOperator(DiagnosticPosition pos,
2524                                  JCTree.Tag optag,
2525                                  Env<AttrContext> env,
2526                                  Type left,
2527                                  Type right) {
2528         return resolveOperator(pos, optag, env, List.of(left, right));
2529     }
2530 
2531     /**
2532      * Resolution of member references is typically done as a single
2533      * overload resolution step, where the argument types A are inferred from
2534      * the target functional descriptor.
2535      *
2536      * If the member reference is a method reference with a type qualifier,
2537      * a two-step lookup process is performed. The first step uses the
2538      * expected argument list A, while the second step discards the first
2539      * type from A (which is treated as a receiver type).
2540      *
2541      * There are two cases in which inference is performed: (i) if the member
2542      * reference is a constructor reference and the qualifier type is raw - in
2543      * which case diamond inference is used to infer a parameterization for the
2544      * type qualifier; (ii) if the member reference is an unbound reference
2545      * where the type qualifier is raw - in that case, during the unbound lookup
2546      * the receiver argument type is used to infer an instantiation for the raw
2547      * qualifier type.
2548      *
2549      * When a multi-step resolution process is exploited, it is an error
2550      * if two candidates are found (ambiguity).
2551      *
2552      * This routine returns a pair (T,S), where S is the member reference symbol,
2553      * and T is the type of the class in which S is defined. This is necessary as
2554      * the type T might be dynamically inferred (i.e. if constructor reference
2555      * has a raw qualifier).
2556      */
2557     Pair<Symbol, ReferenceLookupHelper> resolveMemberReference(DiagnosticPosition pos,
2558                                   Env<AttrContext> env,
2559                                   JCMemberReference referenceTree,
2560                                   Type site,
2561                                   Name name, List<Type> argtypes,
2562                                   List<Type> typeargtypes,
2563                                   boolean boxingAllowed,
2564                                   MethodCheck methodCheck) {
2565         MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC;
2566 
2567         ReferenceLookupHelper boundLookupHelper;
2568         if (!name.equals(names.init)) {
2569             //method reference
2570             boundLookupHelper =
2571                     new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
2572         } else if (site.hasTag(ARRAY)) {
2573             //array constructor reference
2574             boundLookupHelper =
2575                     new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
2576         } else {
2577             //class constructor reference
2578             boundLookupHelper =
2579                     new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
2580         }
2581 
2582         //step 1 - bound lookup
2583         Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
2584         Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, methodCheck, boundLookupHelper);
2585 
2586         //step 2 - unbound lookup
2587         ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup();
2588         Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
2589         Symbol unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, methodCheck, unboundLookupHelper);
2590 
2591         //merge results
2592         Pair<Symbol, ReferenceLookupHelper> res;
2593         if (!lookupSuccess(unboundSym)) {
2594             res = new Pair<Symbol, ReferenceLookupHelper>(boundSym, boundLookupHelper);
2595             env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase;
2596         } else if (lookupSuccess(boundSym)) {
2597             res = new Pair<Symbol, ReferenceLookupHelper>(ambiguityError(boundSym, unboundSym), boundLookupHelper);
2598             env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase;
2599         } else {
2600             res = new Pair<Symbol, ReferenceLookupHelper>(unboundSym, unboundLookupHelper);
2601             env.info.pendingResolutionPhase = unboundEnv.info.pendingResolutionPhase;
2602         }
2603 
2604         return res;
2605     }
2606     //private
2607         boolean lookupSuccess(Symbol s) {
2608             return s.kind == MTH || s.kind == AMBIGUOUS;
2609         }
2610 
2611     /**
2612      * Helper for defining custom method-like lookup logic; a lookup helper
2613      * provides hooks for (i) the actual lookup logic and (ii) accessing the
2614      * lookup result (this step might result in compiler diagnostics to be generated)
2615      */
2616     abstract class LookupHelper {
2617 
2618         /** name of the symbol to lookup */
2619         Name name;
2620 
2621         /** location in which the lookup takes place */
2622         Type site;
2623 
2624         /** actual types used during the lookup */
2625         List<Type> argtypes;
2626 
2627         /** type arguments used during the lookup */
2628         List<Type> typeargtypes;
2629 
2630         /** Max overload resolution phase handled by this helper */
2631         MethodResolutionPhase maxPhase;
2632 
2633         LookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2634             this.name = name;
2635             this.site = site;
2636             this.argtypes = argtypes;
2637             this.typeargtypes = typeargtypes;
2638             this.maxPhase = maxPhase;
2639         }
2640 
2641         /**
2642          * Should lookup stop at given phase with given result
2643          */
2644         protected boolean shouldStop(Symbol sym, MethodResolutionPhase phase) {
2645             return phase.ordinal() > maxPhase.ordinal() ||
2646                     sym.kind < ERRONEOUS || sym.kind == AMBIGUOUS;
2647         }
2648 
2649         /**
2650          * Search for a symbol under a given overload resolution phase - this method
2651          * is usually called several times, once per each overload resolution phase
2652          */
2653         abstract Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase);
2654 
2655         /**
2656          * Validate the result of the lookup
2657          */
2658         abstract Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym);
2659     }
2660 
2661     abstract class BasicLookupHelper extends LookupHelper {
2662 
2663         BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) {
2664             super(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY);
2665         }
2666 
2667         @Override
2668         Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2669             if (sym.kind == AMBIGUOUS) {
2670                 AmbiguityError a_err = (AmbiguityError)sym;
2671                 sym = a_err.mergeAbstracts(site);
2672             }
2673             if (sym.kind >= AMBIGUOUS) {
2674                 //if nothing is found return the 'first' error
2675                 sym = accessMethod(sym, pos, location, site, name, true, argtypes, typeargtypes);
2676             }
2677             return sym;
2678         }
2679     }
2680 
2681     /**
2682      * Helper class for member reference lookup. A reference lookup helper
2683      * defines the basic logic for member reference lookup; a method gives
2684      * access to an 'unbound' helper used to perform an unbound member
2685      * reference lookup.
2686      */
2687     abstract class ReferenceLookupHelper extends LookupHelper {
2688 
2689         /** The member reference tree */
2690         JCMemberReference referenceTree;
2691 
2692         ReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
2693                 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2694             super(name, site, argtypes, typeargtypes, maxPhase);
2695             this.referenceTree = referenceTree;
2696 
2697         }
2698 
2699         /**
2700          * Returns an unbound version of this lookup helper. By default, this
2701          * method returns an dummy lookup helper.
2702          */
2703         ReferenceLookupHelper unboundLookup() {
2704             //dummy loopkup helper that always return 'methodNotFound'
2705             return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
2706                 @Override
2707                 ReferenceLookupHelper unboundLookup() {
2708                     return this;
2709                 }
2710                 @Override
2711                 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2712                     return methodNotFound;
2713                 }
2714                 @Override
2715                 ReferenceKind referenceKind(Symbol sym) {
2716                     Assert.error();
2717                     return null;
2718                 }
2719             };
2720         }
2721 
2722         /**
2723          * Get the kind of the member reference
2724          */
2725         abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym);
2726 
2727         Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2728             if (sym.kind == AMBIGUOUS) {
2729                 AmbiguityError a_err = (AmbiguityError)sym;
2730                 sym = a_err.mergeAbstracts(site);
2731             }
2732             //skip error reporting
2733             return sym;
2734         }
2735     }
2736 
2737     /**
2738      * Helper class for method reference lookup. The lookup logic is based
2739      * upon Resolve.findMethod; in certain cases, this helper class has a
2740      * corresponding unbound helper class (see UnboundMethodReferenceLookupHelper).
2741      * In such cases, non-static lookup results are thrown away.
2742      */
2743     class MethodReferenceLookupHelper extends ReferenceLookupHelper {
2744 
2745         MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
2746                 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2747             super(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
2748         }
2749 
2750         @Override
2751         final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2752             return findMethod(env, site, name, argtypes, typeargtypes,
2753                     phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
2754         }
2755 
2756         @Override
2757         ReferenceLookupHelper unboundLookup() {
2758             if (TreeInfo.isStaticSelector(referenceTree.expr, names) &&
2759                     argtypes.nonEmpty() &&
2760                     (argtypes.head.hasTag(NONE) || types.isSubtypeUnchecked(argtypes.head, site))) {
2761                 return new UnboundMethodReferenceLookupHelper(referenceTree, name,
2762                         site, argtypes, typeargtypes, maxPhase);
2763             } else {
2764                 return super.unboundLookup();
2765             }
2766         }
2767 
2768         @Override
2769         ReferenceKind referenceKind(Symbol sym) {
2770             if (sym.isStatic()) {
2771                 return ReferenceKind.STATIC;
2772             } else {
2773                 Name selName = TreeInfo.name(referenceTree.getQualifierExpression());
2774                 return selName != null && selName == names._super ?
2775                         ReferenceKind.SUPER :
2776                         ReferenceKind.BOUND;
2777             }
2778         }
2779     }
2780 
2781     /**
2782      * Helper class for unbound method reference lookup. Essentially the same
2783      * as the basic method reference lookup helper; main difference is that static
2784      * lookup results are thrown away. If qualifier type is raw, an attempt to
2785      * infer a parameterized type is made using the first actual argument (that
2786      * would otherwise be ignored during the lookup).
2787      */
2788     class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper {
2789 
2790         UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
2791                 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2792             super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase);
2793             if (site.isRaw() && !argtypes.head.hasTag(NONE)) {
2794                 Type asSuperSite = types.asSuper(argtypes.head, site.tsym);
2795                 this.site = asSuperSite;
2796             }
2797         }
2798 
2799         @Override
2800         ReferenceLookupHelper unboundLookup() {
2801             return this;
2802         }
2803 
2804         @Override
2805         ReferenceKind referenceKind(Symbol sym) {
2806             return ReferenceKind.UNBOUND;
2807         }
2808     }
2809 
2810     /**
2811      * Helper class for array constructor lookup; an array constructor lookup
2812      * is simulated by looking up a method that returns the array type specified
2813      * as qualifier, and that accepts a single int parameter (size of the array).
2814      */
2815     class ArrayConstructorReferenceLookupHelper extends ReferenceLookupHelper {
2816 
2817         ArrayConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
2818                 List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2819             super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
2820         }
2821 
2822         @Override
2823         protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2824             Scope sc = new Scope(syms.arrayClass);
2825             MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym);
2826             arrayConstr.type = new MethodType(List.of(syms.intType), site, List.<Type>nil(), syms.methodClass);
2827             sc.enter(arrayConstr);
2828             return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false, false);
2829         }
2830 
2831         @Override
2832         ReferenceKind referenceKind(Symbol sym) {
2833             return ReferenceKind.ARRAY_CTOR;
2834         }
2835     }
2836 
2837     /**
2838      * Helper class for constructor reference lookup. The lookup logic is based
2839      * upon either Resolve.findMethod or Resolve.findDiamond - depending on
2840      * whether the constructor reference needs diamond inference (this is the case
2841      * if the qualifier type is raw). A special erroneous symbol is returned
2842      * if the lookup returns the constructor of an inner class and there's no
2843      * enclosing instance in scope.
2844      */
2845     class ConstructorReferenceLookupHelper extends ReferenceLookupHelper {
2846 
2847         boolean needsInference;
2848 
2849         ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
2850                 List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2851             super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
2852             if (site.isRaw()) {
2853                 this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym);
2854                 needsInference = true;
2855             }
2856         }
2857 
2858         @Override
2859         protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2860             Symbol sym = needsInference ?
2861                 findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
2862                 findMethod(env, site, name, argtypes, typeargtypes,
2863                         phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
2864             return sym.kind != MTH ||
2865                           site.getEnclosingType().hasTag(NONE) ||
2866                           hasEnclosingInstance(env, site) ?
2867                           sym : new InvalidSymbolError(Kinds.MISSING_ENCL, sym, null) {
2868                     @Override
2869                     JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
2870                        return diags.create(dkind, log.currentSource(), pos,
2871                             "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType());
2872                     }
2873                 };
2874         }
2875 
2876         @Override
2877         ReferenceKind referenceKind(Symbol sym) {
2878             return site.getEnclosingType().hasTag(NONE) ?
2879                     ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER;
2880         }
2881     }
2882 
2883     /**
2884      * Main overload resolution routine. On each overload resolution step, a
2885      * lookup helper class is used to perform the method/constructor lookup;
2886      * at the end of the lookup, the helper is used to validate the results
2887      * (this last step might trigger overload resolution diagnostics).
2888      */
2889     Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, MethodCheck methodCheck, LookupHelper lookupHelper) {
2890         MethodResolutionContext resolveContext = new MethodResolutionContext();
2891         resolveContext.methodCheck = methodCheck;
2892         return lookupMethod(env, pos, location, resolveContext, lookupHelper);
2893     }
2894 
2895     Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location,
2896             MethodResolutionContext resolveContext, LookupHelper lookupHelper) {
2897         MethodResolutionContext prevResolutionContext = currentResolutionContext;
2898         try {
2899             Symbol bestSoFar = methodNotFound;
2900             currentResolutionContext = resolveContext;
2901             for (MethodResolutionPhase phase : methodResolutionSteps) {
2902                 if (!phase.isApplicable(boxingEnabled, varargsEnabled) ||
2903                         lookupHelper.shouldStop(bestSoFar, phase)) break;
2904                 MethodResolutionPhase prevPhase = currentResolutionContext.step;
2905                 Symbol prevBest = bestSoFar;
2906                 currentResolutionContext.step = phase;
2907                 bestSoFar = phase.mergeResults(bestSoFar, lookupHelper.lookup(env, phase));
2908                 env.info.pendingResolutionPhase = (prevBest == bestSoFar) ? prevPhase : phase;
2909             }
2910             return lookupHelper.access(env, pos, location, bestSoFar);
2911         } finally {
2912             currentResolutionContext = prevResolutionContext;
2913         }
2914     }
2915 
2916     /**
2917      * Resolve `c.name' where name == this or name == super.
2918      * @param pos           The position to use for error reporting.
2919      * @param env           The environment current at the expression.
2920      * @param c             The qualifier.
2921      * @param name          The identifier's name.
2922      */
2923     Symbol resolveSelf(DiagnosticPosition pos,
2924                        Env<AttrContext> env,
2925                        TypeSymbol c,
2926                        Name name) {
2927         Env<AttrContext> env1 = env;
2928         boolean staticOnly = false;
2929         while (env1.outer != null) {
2930             if (isStatic(env1)) staticOnly = true;
2931             if (env1.enclClass.sym == c) {
2932                 Symbol sym = env1.info.scope.lookup(name).sym;
2933                 if (sym != null) {
2934                     if (staticOnly) sym = new StaticError(sym);
2935                     return accessBase(sym, pos, env.enclClass.sym.type,
2936                                   name, true);
2937                 }
2938             }
2939             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
2940             env1 = env1.outer;
2941         }
2942         if (allowDefaultMethods && c.isInterface() &&
2943                 name == names._super && !isStatic(env) &&
2944                 types.isDirectSuperInterface(c, env.enclClass.sym)) {
2945             //this might be a default super call if one of the superinterfaces is 'c'
2946             for (Type t : pruneInterfaces(env.enclClass.type)) {
2947                 if (t.tsym == c) {
2948                     env.info.defaultSuperCallSite = t;
2949                     return new VarSymbol(0, names._super,
2950                             types.asSuper(env.enclClass.type, c), env.enclClass.sym);
2951                 }
2952             }
2953             //find a direct superinterface that is a subtype of 'c'
2954             for (Type i : types.interfaces(env.enclClass.type)) {
2955                 if (i.tsym.isSubClass(c, types) && i.tsym != c) {
2956                     log.error(pos, "illegal.default.super.call", c,
2957                             diags.fragment("redundant.supertype", c, i));
2958                     return syms.errSymbol;
2959                 }
2960             }
2961             Assert.error();
2962         }
2963         log.error(pos, "not.encl.class", c);
2964         return syms.errSymbol;
2965     }
2966     //where
2967     private List<Type> pruneInterfaces(Type t) {
2968         ListBuffer<Type> result = ListBuffer.lb();
2969         for (Type t1 : types.interfaces(t)) {
2970             boolean shouldAdd = true;
2971             for (Type t2 : types.interfaces(t)) {
2972                 if (t1 != t2 && types.isSubtypeNoCapture(t2, t1)) {
2973                     shouldAdd = false;
2974                 }
2975             }
2976             if (shouldAdd) {
2977                 result.append(t1);
2978             }
2979         }
2980         return result.toList();
2981     }
2982 
2983 
2984     /**
2985      * Resolve `c.this' for an enclosing class c that contains the
2986      * named member.
2987      * @param pos           The position to use for error reporting.
2988      * @param env           The environment current at the expression.
2989      * @param member        The member that must be contained in the result.
2990      */
2991     Symbol resolveSelfContaining(DiagnosticPosition pos,
2992                                  Env<AttrContext> env,
2993                                  Symbol member,
2994                                  boolean isSuperCall) {
2995         Symbol sym = resolveSelfContainingInternal(env, member, isSuperCall);
2996         if (sym == null) {
2997             log.error(pos, "encl.class.required", member);
2998             return syms.errSymbol;
2999         } else {
3000             return accessBase(sym, pos, env.enclClass.sym.type, sym.name, true);
3001         }
3002     }
3003 
3004     boolean hasEnclosingInstance(Env<AttrContext> env, Type type) {
3005         Symbol encl = resolveSelfContainingInternal(env, type.tsym, false);
3006         return encl != null && encl.kind < ERRONEOUS;
3007     }
3008 
3009     private Symbol resolveSelfContainingInternal(Env<AttrContext> env,
3010                                  Symbol member,
3011                                  boolean isSuperCall) {
3012         Name name = names._this;
3013         Env<AttrContext> env1 = isSuperCall ? env.outer : env;
3014         boolean staticOnly = false;
3015         if (env1 != null) {
3016             while (env1 != null && env1.outer != null) {
3017                 if (isStatic(env1)) staticOnly = true;
3018                 if (env1.enclClass.sym.isSubClass(member.owner, types)) {
3019                     Symbol sym = env1.info.scope.lookup(name).sym;
3020                     if (sym != null) {
3021                         if (staticOnly) sym = new StaticError(sym);
3022                         return sym;
3023                     }
3024                 }
3025                 if ((env1.enclClass.sym.flags() & STATIC) != 0)
3026                     staticOnly = true;
3027                 env1 = env1.outer;
3028             }
3029         }
3030         return null;
3031     }
3032 
3033     /**
3034      * Resolve an appropriate implicit this instance for t's container.
3035      * JLS 8.8.5.1 and 15.9.2
3036      */
3037     Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) {
3038         return resolveImplicitThis(pos, env, t, false);
3039     }
3040 
3041     Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t, boolean isSuperCall) {
3042         Type thisType = (((t.tsym.owner.kind & (MTH|VAR)) != 0)
3043                          ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this)
3044                          : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type;
3045         if (env.info.isSelfCall && thisType.tsym == env.enclClass.sym)
3046             log.error(pos, "cant.ref.before.ctor.called", "this");
3047         return thisType;
3048     }
3049 
3050 /* ***************************************************************************
3051  *  ResolveError classes, indicating error situations when accessing symbols
3052  ****************************************************************************/
3053 
3054     //used by TransTypes when checking target type of synthetic cast
3055     public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
3056         AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
3057         logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
3058     }
3059     //where
3060     private void logResolveError(ResolveError error,
3061             DiagnosticPosition pos,
3062             Symbol location,
3063             Type site,
3064             Name name,
3065             List<Type> argtypes,
3066             List<Type> typeargtypes) {
3067         JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
3068                 pos, location, site, name, argtypes, typeargtypes);
3069         if (d != null) {
3070             d.setFlag(DiagnosticFlag.RESOLVE_ERROR);
3071             log.report(d);
3072         }
3073     }
3074 
3075     private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
3076 
3077     public Object methodArguments(List<Type> argtypes) {
3078         if (argtypes == null || argtypes.isEmpty()) {
3079             return noArgs;
3080         } else {
3081             ListBuffer<Object> diagArgs = ListBuffer.lb();
3082             for (Type t : argtypes) {
3083                 if (t.hasTag(DEFERRED)) {
3084                     diagArgs.append(((DeferredAttr.DeferredType)t).tree);
3085                 } else {
3086                     diagArgs.append(t);
3087                 }
3088             }
3089             return diagArgs;
3090         }
3091     }
3092 
3093     /**
3094      * Root class for resolution errors. Subclass of ResolveError
3095      * represent a different kinds of resolution error - as such they must
3096      * specify how they map into concrete compiler diagnostics.
3097      */
3098     abstract class ResolveError extends Symbol {
3099 
3100         /** The name of the kind of error, for debugging only. */
3101         final String debugName;
3102 
3103         ResolveError(int kind, String debugName) {
3104             super(kind, 0, null, null, null);
3105             this.debugName = debugName;
3106         }
3107 
3108         @Override
3109         public <R, P> R accept(ElementVisitor<R, P> v, P p) {
3110             throw new AssertionError();
3111         }
3112 
3113         @Override
3114         public String toString() {
3115             return debugName;
3116         }
3117 
3118         @Override
3119         public boolean exists() {
3120             return false;
3121         }
3122 
3123         /**
3124          * Create an external representation for this erroneous symbol to be
3125          * used during attribution - by default this returns the symbol of a
3126          * brand new error type which stores the original type found
3127          * during resolution.
3128          *
3129          * @param name     the name used during resolution
3130          * @param location the location from which the symbol is accessed
3131          */
3132         protected Symbol access(Name name, TypeSymbol location) {
3133             return types.createErrorType(name, location, syms.errSymbol.type).tsym;
3134         }
3135 
3136         /**
3137          * Create a diagnostic representing this resolution error.
3138          *
3139          * @param dkind     The kind of the diagnostic to be created (e.g error).
3140          * @param pos       The position to be used for error reporting.
3141          * @param site      The original type from where the selection took place.
3142          * @param name      The name of the symbol to be resolved.
3143          * @param argtypes  The invocation's value arguments,
3144          *                  if we looked for a method.
3145          * @param typeargtypes  The invocation's type arguments,
3146          *                      if we looked for a method.
3147          */
3148         abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3149                 DiagnosticPosition pos,
3150                 Symbol location,
3151                 Type site,
3152                 Name name,
3153                 List<Type> argtypes,
3154                 List<Type> typeargtypes);
3155     }
3156 
3157     /**
3158      * This class is the root class of all resolution errors caused by
3159      * an invalid symbol being found during resolution.
3160      */
3161     abstract class InvalidSymbolError extends ResolveError {
3162 
3163         /** The invalid symbol found during resolution */
3164         Symbol sym;
3165 
3166         InvalidSymbolError(int kind, Symbol sym, String debugName) {
3167             super(kind, debugName);
3168             this.sym = sym;
3169         }
3170 
3171         @Override
3172         public boolean exists() {
3173             return true;
3174         }
3175 
3176         @Override
3177         public String toString() {
3178              return super.toString() + " wrongSym=" + sym;
3179         }
3180 
3181         @Override
3182         public Symbol access(Name name, TypeSymbol location) {
3183             if ((sym.kind & ERRONEOUS) == 0 && (sym.kind & TYP) != 0)
3184                 return types.createErrorType(name, location, sym.type).tsym;
3185             else
3186                 return sym;
3187         }
3188     }
3189 
3190     /**
3191      * InvalidSymbolError error class indicating that a symbol matching a
3192      * given name does not exists in a given site.
3193      */
3194     class SymbolNotFoundError extends ResolveError {
3195 
3196         SymbolNotFoundError(int kind) {
3197             super(kind, "symbol not found error");
3198         }
3199 
3200         @Override
3201         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3202                 DiagnosticPosition pos,
3203                 Symbol location,
3204                 Type site,
3205                 Name name,
3206                 List<Type> argtypes,
3207                 List<Type> typeargtypes) {
3208             argtypes = argtypes == null ? List.<Type>nil() : argtypes;
3209             typeargtypes = typeargtypes == null ? List.<Type>nil() : typeargtypes;
3210             if (name == names.error)
3211                 return null;
3212 
3213             if (syms.operatorNames.contains(name)) {
3214                 boolean isUnaryOp = argtypes.size() == 1;
3215                 String key = argtypes.size() == 1 ?
3216                     "operator.cant.be.applied" :
3217                     "operator.cant.be.applied.1";
3218                 Type first = argtypes.head;
3219                 Type second = !isUnaryOp ? argtypes.tail.head : null;
3220                 return diags.create(dkind, log.currentSource(), pos,
3221                         key, name, first, second);
3222             }
3223             boolean hasLocation = false;
3224             if (location == null) {
3225                 location = site.tsym;
3226             }
3227             if (!location.name.isEmpty()) {
3228                 if (location.kind == PCK && !site.tsym.exists()) {
3229                     return diags.create(dkind, log.currentSource(), pos,
3230                         "doesnt.exist", location);
3231                 }
3232                 hasLocation = !location.name.equals(names._this) &&
3233                         !location.name.equals(names._super);
3234             }
3235             boolean isConstructor = kind == ABSENT_MTH && name == names.init;
3236             KindName kindname = isConstructor ? KindName.CONSTRUCTOR : absentKind(kind);
3237             Name idname = isConstructor ? site.tsym.name : name;
3238             String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
3239             if (hasLocation) {
3240                 return diags.create(dkind, log.currentSource(), pos,
3241                         errKey, kindname, idname, //symbol kindname, name
3242                         typeargtypes, args(argtypes), //type parameters and arguments (if any)
3243                         getLocationDiag(location, site)); //location kindname, type
3244             }
3245             else {
3246                 return diags.create(dkind, log.currentSource(), pos,
3247                         errKey, kindname, idname, //symbol kindname, name
3248                         typeargtypes, args(argtypes)); //type parameters and arguments (if any)
3249             }
3250         }
3251         //where
3252         private Object args(List<Type> args) {
3253             return args.isEmpty() ? args : methodArguments(args);
3254         }
3255 
3256         private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) {
3257             String key = "cant.resolve";
3258             String suffix = hasLocation ? ".location" : "";
3259             switch (kindname) {
3260                 case METHOD:
3261                 case CONSTRUCTOR: {
3262                     suffix += ".args";
3263                     suffix += hasTypeArgs ? ".params" : "";
3264                 }
3265             }
3266             return key + suffix;
3267         }
3268         private JCDiagnostic getLocationDiag(Symbol location, Type site) {
3269             if (location.kind == VAR) {
3270                 return diags.fragment("location.1",
3271                     kindName(location),
3272                     location,
3273                     location.type);
3274             } else {
3275                 return diags.fragment("location",
3276                     typeKindName(site),
3277                     site,
3278                     null);
3279             }
3280         }
3281     }
3282 
3283     /**
3284      * InvalidSymbolError error class indicating that a given symbol
3285      * (either a method, a constructor or an operand) is not applicable
3286      * given an actual arguments/type argument list.
3287      */
3288     class InapplicableSymbolError extends ResolveError {
3289 
3290         protected MethodResolutionContext resolveContext;
3291 
3292         InapplicableSymbolError(MethodResolutionContext context) {
3293             this(WRONG_MTH, "inapplicable symbol error", context);
3294         }
3295 
3296         protected InapplicableSymbolError(int kind, String debugName, MethodResolutionContext context) {
3297             super(kind, debugName);
3298             this.resolveContext = context;
3299         }
3300 
3301         @Override
3302         public String toString() {
3303             return super.toString();
3304         }
3305 
3306         @Override
3307         public boolean exists() {
3308             return true;
3309         }
3310 
3311         @Override
3312         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3313                 DiagnosticPosition pos,
3314                 Symbol location,
3315                 Type site,
3316                 Name name,
3317                 List<Type> argtypes,
3318                 List<Type> typeargtypes) {
3319             if (name == names.error)
3320                 return null;
3321 
3322             if (syms.operatorNames.contains(name)) {
3323                 boolean isUnaryOp = argtypes.size() == 1;
3324                 String key = argtypes.size() == 1 ?
3325                     "operator.cant.be.applied" :
3326                     "operator.cant.be.applied.1";
3327                 Type first = argtypes.head;
3328                 Type second = !isUnaryOp ? argtypes.tail.head : null;
3329                 return diags.create(dkind, log.currentSource(), pos,
3330                         key, name, first, second);
3331             }
3332             else {
3333                 Candidate c = errCandidate();
3334                 Symbol ws = c.sym.asMemberOf(site, types);
3335                 return diags.create(dkind, log.currentSource(), pos,
3336                           "cant.apply.symbol",
3337                           kindName(ws),
3338                           ws.name == names.init ? ws.owner.name : ws.name,
3339                           methodArguments(ws.type.getParameterTypes()),
3340                           methodArguments(argtypes),
3341                           kindName(ws.owner),
3342                           ws.owner.type,
3343                           c.details);
3344             }
3345         }
3346 
3347         @Override
3348         public Symbol access(Name name, TypeSymbol location) {
3349             return types.createErrorType(name, location, syms.errSymbol.type).tsym;
3350         }
3351 
3352         private Candidate errCandidate() {
3353             Candidate bestSoFar = null;
3354             for (Candidate c : resolveContext.candidates) {
3355                 if (c.isApplicable()) continue;
3356                 bestSoFar = c;
3357             }
3358             Assert.checkNonNull(bestSoFar);
3359             return bestSoFar;
3360         }
3361     }
3362 
3363     /**
3364      * ResolveError error class indicating that a set of symbols
3365      * (either methods, constructors or operands) is not applicable
3366      * given an actual arguments/type argument list.
3367      */
3368     class InapplicableSymbolsError extends InapplicableSymbolError {
3369 
3370         InapplicableSymbolsError(MethodResolutionContext context) {
3371             super(WRONG_MTHS, "inapplicable symbols", context);
3372         }
3373 
3374         @Override
3375         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3376                 DiagnosticPosition pos,
3377                 Symbol location,
3378                 Type site,
3379                 Name name,
3380                 List<Type> argtypes,
3381                 List<Type> typeargtypes) {
3382             if (!resolveContext.candidates.isEmpty()) {
3383                 JCDiagnostic err = diags.create(dkind,
3384                         log.currentSource(),
3385                         pos,
3386                         "cant.apply.symbols",
3387                         name == names.init ? KindName.CONSTRUCTOR : absentKind(kind),
3388                         name == names.init ? site.tsym.name : name,
3389                         methodArguments(argtypes));
3390                 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site));
3391             } else {
3392                 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
3393                     location, site, name, argtypes, typeargtypes);
3394             }
3395         }
3396 
3397         //where
3398         List<JCDiagnostic> candidateDetails(Type site) {
3399             Map<Symbol, JCDiagnostic> details = new LinkedHashMap<Symbol, JCDiagnostic>();
3400             for (Candidate c : resolveContext.candidates) {
3401                 if (c.isApplicable()) continue;
3402                 JCDiagnostic detailDiag = diags.fragment("inapplicable.method",
3403                         Kinds.kindName(c.sym),
3404                         c.sym.location(site, types),
3405                         c.sym.asMemberOf(site, types),
3406                         c.details);
3407                 details.put(c.sym, detailDiag);
3408             }
3409             return List.from(details.values());
3410         }
3411     }
3412 
3413     /**
3414      * An InvalidSymbolError error class indicating that a symbol is not
3415      * accessible from a given site
3416      */
3417     class AccessError extends InvalidSymbolError {
3418 
3419         private Env<AttrContext> env;
3420         private Type site;
3421 
3422         AccessError(Symbol sym) {
3423             this(null, null, sym);
3424         }
3425 
3426         AccessError(Env<AttrContext> env, Type site, Symbol sym) {
3427             super(HIDDEN, sym, "access error");
3428             this.env = env;
3429             this.site = site;
3430             if (debugResolve)
3431                 log.error("proc.messager", sym + " @ " + site + " is inaccessible.");
3432         }
3433 
3434         @Override
3435         public boolean exists() {
3436             return false;
3437         }
3438 
3439         @Override
3440         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3441                 DiagnosticPosition pos,
3442                 Symbol location,
3443                 Type site,
3444                 Name name,
3445                 List<Type> argtypes,
3446                 List<Type> typeargtypes) {
3447             if (sym.owner.type.hasTag(ERROR))
3448                 return null;
3449 
3450             if (sym.name == names.init && sym.owner != site.tsym) {
3451                 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind,
3452                         pos, location, site, name, argtypes, typeargtypes);
3453             }
3454             else if ((sym.flags() & PUBLIC) != 0
3455                 || (env != null && this.site != null
3456                     && !isAccessible(env, this.site))) {
3457                 return diags.create(dkind, log.currentSource(),
3458                         pos, "not.def.access.class.intf.cant.access",
3459                     sym, sym.location());
3460             }
3461             else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) {
3462                 return diags.create(dkind, log.currentSource(),
3463                         pos, "report.access", sym,
3464                         asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
3465                         sym.location());
3466             }
3467             else {
3468                 return diags.create(dkind, log.currentSource(),
3469                         pos, "not.def.public.cant.access", sym, sym.location());
3470             }
3471         }
3472     }
3473 
3474     /**
3475      * InvalidSymbolError error class indicating that an instance member
3476      * has erroneously been accessed from a static context.
3477      */
3478     class StaticError extends InvalidSymbolError {
3479 
3480         StaticError(Symbol sym) {
3481             super(STATICERR, sym, "static error");
3482         }
3483 
3484         @Override
3485         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3486                 DiagnosticPosition pos,
3487                 Symbol location,
3488                 Type site,
3489                 Name name,
3490                 List<Type> argtypes,
3491                 List<Type> typeargtypes) {
3492             Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS))
3493                 ? types.erasure(sym.type).tsym
3494                 : sym);
3495             return diags.create(dkind, log.currentSource(), pos,
3496                     "non-static.cant.be.ref", kindName(sym), errSym);
3497         }
3498     }
3499 
3500     /**
3501      * InvalidSymbolError error class indicating that a pair of symbols
3502      * (either methods, constructors or operands) are ambiguous
3503      * given an actual arguments/type argument list.
3504      */
3505     class AmbiguityError extends ResolveError {
3506 
3507         /** The other maximally specific symbol */
3508         List<Symbol> ambiguousSyms = List.nil();
3509 
3510         @Override
3511         public boolean exists() {
3512             return true;
3513         }
3514 
3515         AmbiguityError(Symbol sym1, Symbol sym2) {
3516             super(AMBIGUOUS, "ambiguity error");
3517             ambiguousSyms = flatten(sym2).appendList(flatten(sym1));
3518         }
3519 
3520         private List<Symbol> flatten(Symbol sym) {
3521             if (sym.kind == AMBIGUOUS) {
3522                 return ((AmbiguityError)sym).ambiguousSyms;
3523             } else {
3524                 return List.of(sym);
3525             }
3526         }
3527 
3528         AmbiguityError addAmbiguousSymbol(Symbol s) {
3529             ambiguousSyms = ambiguousSyms.prepend(s);
3530             return this;
3531         }
3532 
3533         @Override
3534         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3535                 DiagnosticPosition pos,
3536                 Symbol location,
3537                 Type site,
3538                 Name name,
3539                 List<Type> argtypes,
3540                 List<Type> typeargtypes) {
3541             List<Symbol> diagSyms = ambiguousSyms.reverse();
3542             Symbol s1 = diagSyms.head;
3543             Symbol s2 = diagSyms.tail.head;
3544             Name sname = s1.name;
3545             if (sname == names.init) sname = s1.owner.name;
3546             return diags.create(dkind, log.currentSource(),
3547                       pos, "ref.ambiguous", sname,
3548                       kindName(s1),
3549                       s1,
3550                       s1.location(site, types),
3551                       kindName(s2),
3552                       s2,
3553                       s2.location(site, types));
3554         }
3555 
3556         /**
3557          * If multiple applicable methods are found during overload and none of them
3558          * is more specific than the others, attempt to merge their signatures.
3559          */
3560         Symbol mergeAbstracts(Type site) {
3561             Symbol fst = ambiguousSyms.last();
3562             Symbol res = fst;
3563             for (Symbol s : ambiguousSyms.reverse()) {
3564                 Type mt1 = types.memberType(site, res);
3565                 Type mt2 = types.memberType(site, s);
3566                 if ((s.flags() & ABSTRACT) == 0 ||
3567                         !types.overrideEquivalent(mt1, mt2) ||
3568                         !types.isSameTypes(fst.erasure(types).getParameterTypes(),
3569                                        s.erasure(types).getParameterTypes())) {
3570                     //ambiguity cannot be resolved
3571                     return this;
3572                 } else {
3573                     Type mst = mostSpecificReturnType(mt1, mt2);
3574                     if (mst == null) {
3575                         // Theoretically, this can't happen, but it is possible
3576                         // due to error recovery or mixing incompatible class files
3577                         return this;
3578                     }
3579                     Symbol mostSpecific = mst == mt1 ? res : s;
3580                     List<Type> allThrown = chk.intersect(mt1.getThrownTypes(), mt2.getThrownTypes());
3581                     Type newSig = types.createMethodTypeWithThrown(mostSpecific.type, allThrown);
3582                     res = new MethodSymbol(
3583                             mostSpecific.flags(),
3584                             mostSpecific.name,
3585                             newSig,
3586                             mostSpecific.owner);
3587                 }
3588             }
3589             return res;
3590         }
3591 
3592         @Override
3593         protected Symbol access(Name name, TypeSymbol location) {
3594             Symbol firstAmbiguity = ambiguousSyms.last();
3595             return firstAmbiguity.kind == TYP ?
3596                     types.createErrorType(name, location, firstAmbiguity.type).tsym :
3597                     firstAmbiguity;
3598         }
3599     }
3600 
3601     class BadVarargsMethod extends ResolveError {
3602 
3603         ResolveError delegatedError;
3604 
3605         BadVarargsMethod(ResolveError delegatedError) {
3606             super(delegatedError.kind, "badVarargs");
3607             this.delegatedError = delegatedError;
3608         }
3609 
3610         @Override
3611         public Symbol baseSymbol() {
3612             return delegatedError.baseSymbol();
3613         }
3614 
3615         @Override
3616         protected Symbol access(Name name, TypeSymbol location) {
3617             return delegatedError.access(name, location);
3618         }
3619 
3620         @Override
3621         public boolean exists() {
3622             return true;
3623         }
3624 
3625         @Override
3626         JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
3627             return delegatedError.getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes);
3628         }
3629     }
3630 
3631     enum MethodResolutionPhase {
3632         BASIC(false, false),
3633         BOX(true, false),
3634         VARARITY(true, true) {
3635             @Override
3636             public Symbol mergeResults(Symbol bestSoFar, Symbol sym) {
3637                 switch (sym.kind) {
3638                     case WRONG_MTH:
3639                         return (bestSoFar.kind == WRONG_MTH || bestSoFar.kind == WRONG_MTHS) ?
3640                             bestSoFar :
3641                             sym;
3642                     case ABSENT_MTH:
3643                         return bestSoFar;
3644                     default:
3645                         return sym;
3646                 }
3647             }
3648         };
3649 
3650         final boolean isBoxingRequired;
3651         final boolean isVarargsRequired;
3652 
3653         MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) {
3654            this.isBoxingRequired = isBoxingRequired;
3655            this.isVarargsRequired = isVarargsRequired;
3656         }
3657 
3658         public boolean isBoxingRequired() {
3659             return isBoxingRequired;
3660         }
3661 
3662         public boolean isVarargsRequired() {
3663             return isVarargsRequired;
3664         }
3665 
3666         public boolean isApplicable(boolean boxingEnabled, boolean varargsEnabled) {
3667             return (varargsEnabled || !isVarargsRequired) &&
3668                    (boxingEnabled || !isBoxingRequired);
3669         }
3670 
3671         public Symbol mergeResults(Symbol prev, Symbol sym) {
3672             return sym;
3673         }
3674     }
3675 
3676     final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
3677 
3678     /**
3679      * A resolution context is used to keep track of intermediate results of
3680      * overload resolution, such as list of method that are not applicable
3681      * (used to generate more precise diagnostics) and so on. Resolution contexts
3682      * can be nested - this means that when each overload resolution routine should
3683      * work within the resolution context it created.
3684      */
3685     class MethodResolutionContext {
3686 
3687         private List<Candidate> candidates = List.nil();
3688 
3689         MethodResolutionPhase step = null;
3690 
3691         MethodCheck methodCheck = resolveMethodCheck;
3692 
3693         private boolean internalResolution = false;
3694         private DeferredAttr.AttrMode attrMode = DeferredAttr.AttrMode.SPECULATIVE;
3695 
3696         void addInapplicableCandidate(Symbol sym, JCDiagnostic details) {
3697             Candidate c = new Candidate(currentResolutionContext.step, sym, details, null);
3698             candidates = candidates.append(c);
3699         }
3700 
3701         void addApplicableCandidate(Symbol sym, Type mtype) {
3702             Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype);
3703             candidates = candidates.append(c);
3704         }
3705 
3706         DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext, ResultInfo pendingResult, Warner warn) {
3707             return deferredAttr.new DeferredAttrContext(attrMode, sym, step, inferenceContext, pendingResult != null ? pendingResult.checkContext.deferredAttrContext() : deferredAttr.emptyDeferredAttrContext, warn);
3708         }
3709 
3710         /**
3711          * This class represents an overload resolution candidate. There are two
3712          * kinds of candidates: applicable methods and inapplicable methods;
3713          * applicable methods have a pointer to the instantiated method type,
3714          * while inapplicable candidates contain further details about the
3715          * reason why the method has been considered inapplicable.
3716          */
3717         @SuppressWarnings("overrides")
3718         class Candidate {
3719 
3720             final MethodResolutionPhase step;
3721             final Symbol sym;
3722             final JCDiagnostic details;
3723             final Type mtype;
3724 
3725             private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
3726                 this.step = step;
3727                 this.sym = sym;
3728                 this.details = details;
3729                 this.mtype = mtype;
3730             }
3731 
3732             @Override
3733             public boolean equals(Object o) {
3734                 if (o instanceof Candidate) {
3735                     Symbol s1 = this.sym;
3736                     Symbol s2 = ((Candidate)o).sym;
3737                     if  ((s1 != s2 &&
3738                             (s1.overrides(s2, s1.owner.type.tsym, types, false) ||
3739                             (s2.overrides(s1, s2.owner.type.tsym, types, false)))) ||
3740                             ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner))
3741                         return true;
3742                 }
3743                 return false;
3744             }
3745 
3746             boolean isApplicable() {
3747                 return mtype != null;
3748             }
3749         }
3750 
3751         DeferredAttr.AttrMode attrMode() {
3752             return attrMode;
3753         }
3754 
3755         boolean internal() {
3756             return internalResolution;
3757         }
3758     }
3759 
3760     MethodResolutionContext currentResolutionContext = null;
3761 }