Home » openjdk-7 » com.sun.tools » javac » comp » [javadoc | source]

    1   /*
    2    * Copyright (c) 1999, 2011, 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.util;
   29   import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
   30   import com.sun.tools.javac.code;
   31   import com.sun.tools.javac.jvm;
   32   import com.sun.tools.javac.tree;
   33   import com.sun.tools.javac.api.Formattable.LocalizedString;
   34   import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
   35   
   36   import com.sun.tools.javac.code.Type;
   37   import com.sun.tools.javac.code.Symbol;
   38   import com.sun.tools.javac.tree.JCTree;
   39   
   40   import static com.sun.tools.javac.code.Flags.*;
   41   import static com.sun.tools.javac.code.Kinds.*;
   42   import static com.sun.tools.javac.code.TypeTags.*;
   43   import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
   44   import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
   45   import javax.lang.model.element.ElementVisitor;
   46   
   47   import java.util.Map;
   48   import java.util.Set;
   49   import java.util.HashMap;
   50   import java.util.HashSet;
   51   
   52   /** Helper class for name resolution, used mostly by the attribution phase.
   53    *
   54    *  <p><b>This is NOT part of any supported API.
   55    *  If you write code that depends on this, you do so at your own risk.
   56    *  This code and its internal interfaces are subject to change or
   57    *  deletion without notice.</b>
   58    */
   59   public class Resolve {
   60       protected static final Context.Key<Resolve> resolveKey =
   61           new Context.Key<Resolve>();
   62   
   63       Names names;
   64       Log log;
   65       Symtab syms;
   66       Check chk;
   67       Infer infer;
   68       ClassReader reader;
   69       TreeInfo treeinfo;
   70       Types types;
   71       JCDiagnostic.Factory diags;
   72       public final boolean boxingEnabled; // = source.allowBoxing();
   73       public final boolean varargsEnabled; // = source.allowVarargs();
   74       public final boolean allowMethodHandles;
   75       private final boolean debugResolve;
   76   
   77       Scope polymorphicSignatureScope;
   78   
   79       public static Resolve instance(Context context) {
   80           Resolve instance = context.get(resolveKey);
   81           if (instance == null)
   82               instance = new Resolve(context);
   83           return instance;
   84       }
   85   
   86       protected Resolve(Context context) {
   87           context.put(resolveKey, this);
   88           syms = Symtab.instance(context);
   89   
   90           varNotFound = new
   91               SymbolNotFoundError(ABSENT_VAR);
   92           wrongMethod = new
   93               InapplicableSymbolError(syms.errSymbol);
   94           wrongMethods = new
   95               InapplicableSymbolsError(syms.errSymbol);
   96           methodNotFound = new
   97               SymbolNotFoundError(ABSENT_MTH);
   98           typeNotFound = new
   99               SymbolNotFoundError(ABSENT_TYP);
  100   
  101           names = Names.instance(context);
  102           log = Log.instance(context);
  103           chk = Check.instance(context);
  104           infer = Infer.instance(context);
  105           reader = ClassReader.instance(context);
  106           treeinfo = TreeInfo.instance(context);
  107           types = Types.instance(context);
  108           diags = JCDiagnostic.Factory.instance(context);
  109           Source source = Source.instance(context);
  110           boxingEnabled = source.allowBoxing();
  111           varargsEnabled = source.allowVarargs();
  112           Options options = Options.instance(context);
  113           debugResolve = options.isSet("debugresolve");
  114           Target target = Target.instance(context);
  115           allowMethodHandles = target.hasMethodHandles();
  116           polymorphicSignatureScope = new Scope(syms.noSymbol);
  117   
  118           inapplicableMethodException = new InapplicableMethodException(diags);
  119       }
  120   
  121       /** error symbols, which are returned when resolution fails
  122        */
  123       final SymbolNotFoundError varNotFound;
  124       final InapplicableSymbolError wrongMethod;
  125       final InapplicableSymbolsError wrongMethods;
  126       final SymbolNotFoundError methodNotFound;
  127       final SymbolNotFoundError typeNotFound;
  128   
  129   /* ************************************************************************
  130    * Identifier resolution
  131    *************************************************************************/
  132   
  133       /** An environment is "static" if its static level is greater than
  134        *  the one of its outer environment
  135        */
  136       static boolean isStatic(Env<AttrContext> env) {
  137           return env.info.staticLevel > env.outer.info.staticLevel;
  138       }
  139   
  140       /** An environment is an "initializer" if it is a constructor or
  141        *  an instance initializer.
  142        */
  143       static boolean isInitializer(Env<AttrContext> env) {
  144           Symbol owner = env.info.scope.owner;
  145           return owner.isConstructor() ||
  146               owner.owner.kind == TYP &&
  147               (owner.kind == VAR ||
  148                owner.kind == MTH && (owner.flags() & BLOCK) != 0) &&
  149               (owner.flags() & STATIC) == 0;
  150       }
  151   
  152       /** Is class accessible in given evironment?
  153        *  @param env    The current environment.
  154        *  @param c      The class whose accessibility is checked.
  155        */
  156       public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) {
  157           return isAccessible(env, c, false);
  158       }
  159   
  160       public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) {
  161           boolean isAccessible = false;
  162           switch ((short)(c.flags() & AccessFlags)) {
  163               case PRIVATE:
  164                   isAccessible =
  165                       env.enclClass.sym.outermostClass() ==
  166                       c.owner.outermostClass();
  167                   break;
  168               case 0:
  169                   isAccessible =
  170                       env.toplevel.packge == c.owner // fast special case
  171                       ||
  172                       env.toplevel.packge == c.packge()
  173                       ||
  174                       // Hack: this case is added since synthesized default constructors
  175                       // of anonymous classes should be allowed to access
  176                       // classes which would be inaccessible otherwise.
  177                       env.enclMethod != null &&
  178                       (env.enclMethod.mods.flags & ANONCONSTR) != 0;
  179                   break;
  180               default: // error recovery
  181               case PUBLIC:
  182                   isAccessible = true;
  183                   break;
  184               case PROTECTED:
  185                   isAccessible =
  186                       env.toplevel.packge == c.owner // fast special case
  187                       ||
  188                       env.toplevel.packge == c.packge()
  189                       ||
  190                       isInnerSubClass(env.enclClass.sym, c.owner);
  191                   break;
  192           }
  193           return (checkInner == false || c.type.getEnclosingType() == Type.noType) ?
  194               isAccessible :
  195               isAccessible && isAccessible(env, c.type.getEnclosingType(), checkInner);
  196       }
  197       //where
  198           /** Is given class a subclass of given base class, or an inner class
  199            *  of a subclass?
  200            *  Return null if no such class exists.
  201            *  @param c     The class which is the subclass or is contained in it.
  202            *  @param base  The base class
  203            */
  204           private boolean isInnerSubClass(ClassSymbol c, Symbol base) {
  205               while (c != null && !c.isSubClass(base, types)) {
  206                   c = c.owner.enclClass();
  207               }
  208               return c != null;
  209           }
  210   
  211       boolean isAccessible(Env<AttrContext> env, Type t) {
  212           return isAccessible(env, t, false);
  213       }
  214   
  215       boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) {
  216           return (t.tag == ARRAY)
  217               ? isAccessible(env, types.elemtype(t))
  218               : isAccessible(env, t.tsym, checkInner);
  219       }
  220   
  221       /** Is symbol accessible as a member of given type in given evironment?
  222        *  @param env    The current environment.
  223        *  @param site   The type of which the tested symbol is regarded
  224        *                as a member.
  225        *  @param sym    The symbol.
  226        */
  227       public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) {
  228           return isAccessible(env, site, sym, false);
  229       }
  230       public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) {
  231           if (sym.name == names.init && sym.owner != site.tsym) return false;
  232           switch ((short)(sym.flags() & AccessFlags)) {
  233           case PRIVATE:
  234               return
  235                   (env.enclClass.sym == sym.owner // fast special case
  236                    ||
  237                    env.enclClass.sym.outermostClass() ==
  238                    sym.owner.outermostClass())
  239                   &&
  240                   sym.isInheritedIn(site.tsym, types);
  241           case 0:
  242               return
  243                   (env.toplevel.packge == sym.owner.owner // fast special case
  244                    ||
  245                    env.toplevel.packge == sym.packge())
  246                   &&
  247                   isAccessible(env, site, checkInner)
  248                   &&
  249                   sym.isInheritedIn(site.tsym, types)
  250                   &&
  251                   notOverriddenIn(site, sym);
  252           case PROTECTED:
  253               return
  254                   (env.toplevel.packge == sym.owner.owner // fast special case
  255                    ||
  256                    env.toplevel.packge == sym.packge()
  257                    ||
  258                    isProtectedAccessible(sym, env.enclClass.sym, site)
  259                    ||
  260                    // OK to select instance method or field from 'super' or type name
  261                    // (but type names should be disallowed elsewhere!)
  262                    env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP)
  263                   &&
  264                   isAccessible(env, site, checkInner)
  265                   &&
  266                   notOverriddenIn(site, sym);
  267           default: // this case includes erroneous combinations as well
  268               return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym);
  269           }
  270       }
  271       //where
  272       /* `sym' is accessible only if not overridden by
  273        * another symbol which is a member of `site'
  274        * (because, if it is overridden, `sym' is not strictly
  275        * speaking a member of `site'). A polymorphic signature method
  276        * cannot be overridden (e.g. MH.invokeExact(Object[])).
  277        */
  278       private boolean notOverriddenIn(Type site, Symbol sym) {
  279           if (sym.kind != MTH || sym.isConstructor() || sym.isStatic())
  280               return true;
  281           else {
  282               Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true);
  283               return (s2 == null || s2 == sym || sym.owner == s2.owner ||
  284                       s2.isPolymorphicSignatureGeneric() ||
  285                       !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
  286           }
  287       }
  288       //where
  289           /** Is given protected symbol accessible if it is selected from given site
  290            *  and the selection takes place in given class?
  291            *  @param sym     The symbol with protected access
  292            *  @param c       The class where the access takes place
  293            *  @site          The type of the qualifier
  294            */
  295           private
  296           boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) {
  297               while (c != null &&
  298                      !(c.isSubClass(sym.owner, types) &&
  299                        (c.flags() & INTERFACE) == 0 &&
  300                        // In JLS 2e 6.6.2.1, the subclass restriction applies
  301                        // only to instance fields and methods -- types are excluded
  302                        // regardless of whether they are declared 'static' or not.
  303                        ((sym.flags() & STATIC) != 0 || sym.kind == TYP || site.tsym.isSubClass(c, types))))
  304                   c = c.owner.enclClass();
  305               return c != null;
  306           }
  307   
  308       /** Try to instantiate the type of a method so that it fits
  309        *  given type arguments and argument types. If succesful, return
  310        *  the method's instantiated type, else return null.
  311        *  The instantiation will take into account an additional leading
  312        *  formal parameter if the method is an instance method seen as a member
  313        *  of un underdetermined site In this case, we treat site as an additional
  314        *  parameter and the parameters of the class containing the method as
  315        *  additional type variables that get instantiated.
  316        *
  317        *  @param env         The current environment
  318        *  @param site        The type of which the method is a member.
  319        *  @param m           The method symbol.
  320        *  @param argtypes    The invocation's given value arguments.
  321        *  @param typeargtypes    The invocation's given type arguments.
  322        *  @param allowBoxing Allow boxing conversions of arguments.
  323        *  @param useVarargs Box trailing arguments into an array for varargs.
  324        */
  325       Type rawInstantiate(Env<AttrContext> env,
  326                           Type site,
  327                           Symbol m,
  328                           List<Type> argtypes,
  329                           List<Type> typeargtypes,
  330                           boolean allowBoxing,
  331                           boolean useVarargs,
  332                           Warner warn)
  333           throws Infer.InferenceException {
  334           boolean polymorphicSignature = m.isPolymorphicSignatureGeneric() && allowMethodHandles;
  335           if (useVarargs && (m.flags() & VARARGS) == 0)
  336               throw inapplicableMethodException.setMessage();
  337           Type mt = types.memberType(site, m);
  338   
  339           // tvars is the list of formal type variables for which type arguments
  340           // need to inferred.
  341           List<Type> tvars = null;
  342           if (env.info.tvars != null) {
  343               tvars = types.newInstances(env.info.tvars);
  344               mt = types.subst(mt, env.info.tvars, tvars);
  345           }
  346           if (typeargtypes == null) typeargtypes = List.nil();
  347           if (mt.tag != FORALL && typeargtypes.nonEmpty()) {
  348               // This is not a polymorphic method, but typeargs are supplied
  349               // which is fine, see JLS 15.12.2.1
  350           } else if (mt.tag == FORALL && typeargtypes.nonEmpty()) {
  351               ForAll pmt = (ForAll) mt;
  352               if (typeargtypes.length() != pmt.tvars.length())
  353                   throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
  354               // Check type arguments are within bounds
  355               List<Type> formals = pmt.tvars;
  356               List<Type> actuals = typeargtypes;
  357               while (formals.nonEmpty() && actuals.nonEmpty()) {
  358                   List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head),
  359                                                   pmt.tvars, typeargtypes);
  360                   for (; bounds.nonEmpty(); bounds = bounds.tail)
  361                       if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn))
  362                           throw inapplicableMethodException.setMessage("explicit.param.do.not.conform.to.bounds",actuals.head, bounds);
  363                   formals = formals.tail;
  364                   actuals = actuals.tail;
  365               }
  366               mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes);
  367           } else if (mt.tag == FORALL) {
  368               ForAll pmt = (ForAll) mt;
  369               List<Type> tvars1 = types.newInstances(pmt.tvars);
  370               tvars = tvars.appendList(tvars1);
  371               mt = types.subst(pmt.qtype, pmt.tvars, tvars1);
  372           }
  373   
  374           // find out whether we need to go the slow route via infer
  375           boolean instNeeded = tvars.tail != null || /*inlined: tvars.nonEmpty()*/
  376                   polymorphicSignature;
  377           for (List<Type> l = argtypes;
  378                l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
  379                l = l.tail) {
  380               if (l.head.tag == FORALL) instNeeded = true;
  381           }
  382   
  383           if (instNeeded)
  384               return polymorphicSignature ?
  385                   infer.instantiatePolymorphicSignatureInstance(env, site, m.name, (MethodSymbol)m, argtypes) :
  386                   infer.instantiateMethod(env,
  387                                       tvars,
  388                                       (MethodType)mt,
  389                                       m,
  390                                       argtypes,
  391                                       allowBoxing,
  392                                       useVarargs,
  393                                       warn);
  394   
  395           checkRawArgumentsAcceptable(env, argtypes, mt.getParameterTypes(),
  396                                   allowBoxing, useVarargs, warn);
  397           return mt;
  398       }
  399   
  400       /** Same but returns null instead throwing a NoInstanceException
  401        */
  402       Type instantiate(Env<AttrContext> env,
  403                        Type site,
  404                        Symbol m,
  405                        List<Type> argtypes,
  406                        List<Type> typeargtypes,
  407                        boolean allowBoxing,
  408                        boolean useVarargs,
  409                        Warner warn) {
  410           try {
  411               return rawInstantiate(env, site, m, argtypes, typeargtypes,
  412                                     allowBoxing, useVarargs, warn);
  413           } catch (InapplicableMethodException ex) {
  414               return null;
  415           }
  416       }
  417   
  418       /** Check if a parameter list accepts a list of args.
  419        */
  420       boolean argumentsAcceptable(Env<AttrContext> env,
  421                                   List<Type> argtypes,
  422                                   List<Type> formals,
  423                                   boolean allowBoxing,
  424                                   boolean useVarargs,
  425                                   Warner warn) {
  426           try {
  427               checkRawArgumentsAcceptable(env, argtypes, formals, allowBoxing, useVarargs, warn);
  428               return true;
  429           } catch (InapplicableMethodException ex) {
  430               return false;
  431           }
  432       }
  433       void checkRawArgumentsAcceptable(Env<AttrContext> env,
  434                                   List<Type> argtypes,
  435                                   List<Type> formals,
  436                                   boolean allowBoxing,
  437                                   boolean useVarargs,
  438                                   Warner warn) {
  439           Type varargsFormal = useVarargs ? formals.last() : null;
  440           if (varargsFormal == null &&
  441                   argtypes.size() != formals.size()) {
  442               throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
  443           }
  444   
  445           while (argtypes.nonEmpty() && formals.head != varargsFormal) {
  446               boolean works = allowBoxing
  447                   ? types.isConvertible(argtypes.head, formals.head, warn)
  448                   : types.isSubtypeUnchecked(argtypes.head, formals.head, warn);
  449               if (!works)
  450                   throw inapplicableMethodException.setMessage("no.conforming.assignment.exists",
  451                           argtypes.head,
  452                           formals.head);
  453               argtypes = argtypes.tail;
  454               formals = formals.tail;
  455           }
  456   
  457           if (formals.head != varargsFormal)
  458               throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
  459   
  460           if (useVarargs) {
  461               Type elt = types.elemtype(varargsFormal);
  462               while (argtypes.nonEmpty()) {
  463                   if (!types.isConvertible(argtypes.head, elt, warn))
  464                       throw inapplicableMethodException.setMessage("varargs.argument.mismatch",
  465                               argtypes.head,
  466                               elt);
  467                   argtypes = argtypes.tail;
  468               }
  469               //check varargs element type accessibility
  470               if (!isAccessible(env, elt)) {
  471                   Symbol location = env.enclClass.sym;
  472                   throw inapplicableMethodException.setMessage("inaccessible.varargs.type",
  473                               elt,
  474                               Kinds.kindName(location),
  475                               location);
  476               }
  477           }
  478           return;
  479       }
  480       // where
  481           public static class InapplicableMethodException extends RuntimeException {
  482               private static final long serialVersionUID = 0;
  483   
  484               JCDiagnostic diagnostic;
  485               JCDiagnostic.Factory diags;
  486   
  487               InapplicableMethodException(JCDiagnostic.Factory diags) {
  488                   this.diagnostic = null;
  489                   this.diags = diags;
  490               }
  491               InapplicableMethodException setMessage() {
  492                   this.diagnostic = null;
  493                   return this;
  494               }
  495               InapplicableMethodException setMessage(String key) {
  496                   this.diagnostic = key != null ? diags.fragment(key) : null;
  497                   return this;
  498               }
  499               InapplicableMethodException setMessage(String key, Object... args) {
  500                   this.diagnostic = key != null ? diags.fragment(key, args) : null;
  501                   return this;
  502               }
  503               InapplicableMethodException setMessage(JCDiagnostic diag) {
  504                   this.diagnostic = diag;
  505                   return this;
  506               }
  507   
  508               public JCDiagnostic getDiagnostic() {
  509                   return diagnostic;
  510               }
  511           }
  512           private final InapplicableMethodException inapplicableMethodException;
  513   
  514   /* ***************************************************************************
  515    *  Symbol lookup
  516    *  the following naming conventions for arguments are used
  517    *
  518    *       env      is the environment where the symbol was mentioned
  519    *       site     is the type of which the symbol is a member
  520    *       name     is the symbol's name
  521    *                if no arguments are given
  522    *       argtypes are the value arguments, if we search for a method
  523    *
  524    *  If no symbol was found, a ResolveError detailing the problem is returned.
  525    ****************************************************************************/
  526   
  527       /** Find field. Synthetic fields are always skipped.
  528        *  @param env     The current environment.
  529        *  @param site    The original type from where the selection takes place.
  530        *  @param name    The name of the field.
  531        *  @param c       The class to search for the field. This is always
  532        *                 a superclass or implemented interface of site's class.
  533        */
  534       Symbol findField(Env<AttrContext> env,
  535                        Type site,
  536                        Name name,
  537                        TypeSymbol c) {
  538           while (c.type.tag == TYPEVAR)
  539               c = c.type.getUpperBound().tsym;
  540           Symbol bestSoFar = varNotFound;
  541           Symbol sym;
  542           Scope.Entry e = c.members().lookup(name);
  543           while (e.scope != null) {
  544               if (e.sym.kind == VAR && (e.sym.flags_field & SYNTHETIC) == 0) {
  545                   return isAccessible(env, site, e.sym)
  546                       ? e.sym : new AccessError(env, site, e.sym);
  547               }
  548               e = e.next();
  549           }
  550           Type st = types.supertype(c.type);
  551           if (st != null && (st.tag == CLASS || st.tag == TYPEVAR)) {
  552               sym = findField(env, site, name, st.tsym);
  553               if (sym.kind < bestSoFar.kind) bestSoFar = sym;
  554           }
  555           for (List<Type> l = types.interfaces(c.type);
  556                bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
  557                l = l.tail) {
  558               sym = findField(env, site, name, l.head.tsym);
  559               if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&
  560                   sym.owner != bestSoFar.owner)
  561                   bestSoFar = new AmbiguityError(bestSoFar, sym);
  562               else if (sym.kind < bestSoFar.kind)
  563                   bestSoFar = sym;
  564           }
  565           return bestSoFar;
  566       }
  567   
  568       /** Resolve a field identifier, throw a fatal error if not found.
  569        *  @param pos       The position to use for error reporting.
  570        *  @param env       The environment current at the method invocation.
  571        *  @param site      The type of the qualifying expression, in which
  572        *                   identifier is searched.
  573        *  @param name      The identifier's name.
  574        */
  575       public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env,
  576                                             Type site, Name name) {
  577           Symbol sym = findField(env, site, name, site.tsym);
  578           if (sym.kind == VAR) return (VarSymbol)sym;
  579           else throw new FatalError(
  580                    diags.fragment("fatal.err.cant.locate.field",
  581                                   name));
  582       }
  583   
  584       /** Find unqualified variable or field with given name.
  585        *  Synthetic fields always skipped.
  586        *  @param env     The current environment.
  587        *  @param name    The name of the variable or field.
  588        */
  589       Symbol findVar(Env<AttrContext> env, Name name) {
  590           Symbol bestSoFar = varNotFound;
  591           Symbol sym;
  592           Env<AttrContext> env1 = env;
  593           boolean staticOnly = false;
  594           while (env1.outer != null) {
  595               if (isStatic(env1)) staticOnly = true;
  596               Scope.Entry e = env1.info.scope.lookup(name);
  597               while (e.scope != null &&
  598                      (e.sym.kind != VAR ||
  599                       (e.sym.flags_field & SYNTHETIC) != 0))
  600                   e = e.next();
  601               sym = (e.scope != null)
  602                   ? e.sym
  603                   : findField(
  604                       env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
  605               if (sym.exists()) {
  606                   if (staticOnly &&
  607                       sym.kind == VAR &&
  608                       sym.owner.kind == TYP &&
  609                       (sym.flags() & STATIC) == 0)
  610                       return new StaticError(sym);
  611                   else
  612                       return sym;
  613               } else if (sym.kind < bestSoFar.kind) {
  614                   bestSoFar = sym;
  615               }
  616   
  617               if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
  618               env1 = env1.outer;
  619           }
  620   
  621           sym = findField(env, syms.predefClass.type, name, syms.predefClass);
  622           if (sym.exists())
  623               return sym;
  624           if (bestSoFar.exists())
  625               return bestSoFar;
  626   
  627           Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
  628           for (; e.scope != null; e = e.next()) {
  629               sym = e.sym;
  630               Type origin = e.getOrigin().owner.type;
  631               if (sym.kind == VAR) {
  632                   if (e.sym.owner.type != origin)
  633                       sym = sym.clone(e.getOrigin().owner);
  634                   return isAccessible(env, origin, sym)
  635                       ? sym : new AccessError(env, origin, sym);
  636               }
  637           }
  638   
  639           Symbol origin = null;
  640           e = env.toplevel.starImportScope.lookup(name);
  641           for (; e.scope != null; e = e.next()) {
  642               sym = e.sym;
  643               if (sym.kind != VAR)
  644                   continue;
  645               // invariant: sym.kind == VAR
  646               if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner)
  647                   return new AmbiguityError(bestSoFar, sym);
  648               else if (bestSoFar.kind >= VAR) {
  649                   origin = e.getOrigin().owner;
  650                   bestSoFar = isAccessible(env, origin.type, sym)
  651                       ? sym : new AccessError(env, origin.type, sym);
  652               }
  653           }
  654           if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type)
  655               return bestSoFar.clone(origin);
  656           else
  657               return bestSoFar;
  658       }
  659   
  660       Warner noteWarner = new Warner();
  661   
  662       /** Select the best method for a call site among two choices.
  663        *  @param env              The current environment.
  664        *  @param site             The original type from where the
  665        *                          selection takes place.
  666        *  @param argtypes         The invocation's value arguments,
  667        *  @param typeargtypes     The invocation's type arguments,
  668        *  @param sym              Proposed new best match.
  669        *  @param bestSoFar        Previously found best match.
  670        *  @param allowBoxing Allow boxing conversions of arguments.
  671        *  @param useVarargs Box trailing arguments into an array for varargs.
  672        */
  673       @SuppressWarnings("fallthrough")
  674       Symbol selectBest(Env<AttrContext> env,
  675                         Type site,
  676                         List<Type> argtypes,
  677                         List<Type> typeargtypes,
  678                         Symbol sym,
  679                         Symbol bestSoFar,
  680                         boolean allowBoxing,
  681                         boolean useVarargs,
  682                         boolean operator) {
  683           if (sym.kind == ERR) return bestSoFar;
  684           if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
  685           Assert.check(sym.kind < AMBIGUOUS);
  686           try {
  687               rawInstantiate(env, site, sym, argtypes, typeargtypes,
  688                                  allowBoxing, useVarargs, Warner.noWarnings);
  689           } catch (InapplicableMethodException ex) {
  690               switch (bestSoFar.kind) {
  691               case ABSENT_MTH:
  692                   return wrongMethod.setWrongSym(sym, ex.getDiagnostic());
  693               case WRONG_MTH:
  694                   wrongMethods.addCandidate(currentStep, wrongMethod.sym, wrongMethod.explanation);
  695               case WRONG_MTHS:
  696                   return wrongMethods.addCandidate(currentStep, sym, ex.getDiagnostic());
  697               default:
  698                   return bestSoFar;
  699               }
  700           }
  701           if (!isAccessible(env, site, sym)) {
  702               return (bestSoFar.kind == ABSENT_MTH)
  703                   ? new AccessError(env, site, sym)
  704                   : bestSoFar;
  705               }
  706           return (bestSoFar.kind > AMBIGUOUS)
  707               ? sym
  708               : mostSpecific(sym, bestSoFar, env, site,
  709                              allowBoxing && operator, useVarargs);
  710       }
  711   
  712       /* Return the most specific of the two methods for a call,
  713        *  given that both are accessible and applicable.
  714        *  @param m1               A new candidate for most specific.
  715        *  @param m2               The previous most specific candidate.
  716        *  @param env              The current environment.
  717        *  @param site             The original type from where the selection
  718        *                          takes place.
  719        *  @param allowBoxing Allow boxing conversions of arguments.
  720        *  @param useVarargs Box trailing arguments into an array for varargs.
  721        */
  722       Symbol mostSpecific(Symbol m1,
  723                           Symbol m2,
  724                           Env<AttrContext> env,
  725                           final Type site,
  726                           boolean allowBoxing,
  727                           boolean useVarargs) {
  728           switch (m2.kind) {
  729           case MTH:
  730               if (m1 == m2) return m1;
  731               boolean m1SignatureMoreSpecific = signatureMoreSpecific(env, site, m1, m2, allowBoxing, useVarargs);
  732               boolean m2SignatureMoreSpecific = signatureMoreSpecific(env, site, m2, m1, allowBoxing, useVarargs);
  733               if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) {
  734                   Type mt1 = types.memberType(site, m1);
  735                   Type mt2 = types.memberType(site, m2);
  736                   if (!types.overrideEquivalent(mt1, mt2))
  737                       return ambiguityError(m1, m2);
  738   
  739                   // same signature; select (a) the non-bridge method, or
  740                   // (b) the one that overrides the other, or (c) the concrete
  741                   // one, or (d) merge both abstract signatures
  742                   if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE))
  743                       return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
  744   
  745                   // if one overrides or hides the other, use it
  746                   TypeSymbol m1Owner = (TypeSymbol)m1.owner;
  747                   TypeSymbol m2Owner = (TypeSymbol)m2.owner;
  748                   if (types.asSuper(m1Owner.type, m2Owner) != null &&
  749                       ((m1.owner.flags_field & INTERFACE) == 0 ||
  750                        (m2.owner.flags_field & INTERFACE) != 0) &&
  751                       m1.overrides(m2, m1Owner, types, false))
  752                       return m1;
  753                   if (types.asSuper(m2Owner.type, m1Owner) != null &&
  754                       ((m2.owner.flags_field & INTERFACE) == 0 ||
  755                        (m1.owner.flags_field & INTERFACE) != 0) &&
  756                       m2.overrides(m1, m2Owner, types, false))
  757                       return m2;
  758                   boolean m1Abstract = (m1.flags() & ABSTRACT) != 0;
  759                   boolean m2Abstract = (m2.flags() & ABSTRACT) != 0;
  760                   if (m1Abstract && !m2Abstract) return m2;
  761                   if (m2Abstract && !m1Abstract) return m1;
  762                   // both abstract or both concrete
  763                   if (!m1Abstract && !m2Abstract)
  764                       return ambiguityError(m1, m2);
  765                   // check that both signatures have the same erasure
  766                   if (!types.isSameTypes(m1.erasure(types).getParameterTypes(),
  767                                          m2.erasure(types).getParameterTypes()))
  768                       return ambiguityError(m1, m2);
  769                   // both abstract, neither overridden; merge throws clause and result type
  770                   Symbol mostSpecific;
  771                   if (types.returnTypeSubstitutable(mt1, mt2))
  772                       mostSpecific = m1;
  773                   else if (types.returnTypeSubstitutable(mt2, mt1))
  774                       mostSpecific = m2;
  775                   else {
  776                       // Theoretically, this can't happen, but it is possible
  777                       // due to error recovery or mixing incompatible class files
  778                       return ambiguityError(m1, m2);
  779                   }
  780                   List<Type> allThrown = chk.intersect(mt1.getThrownTypes(), mt2.getThrownTypes());
  781                   Type newSig = types.createMethodTypeWithThrown(mostSpecific.type, allThrown);
  782                   MethodSymbol result = new MethodSymbol(
  783                           mostSpecific.flags(),
  784                           mostSpecific.name,
  785                           newSig,
  786                           mostSpecific.owner) {
  787                       @Override
  788                       public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
  789                           if (origin == site.tsym)
  790                               return this;
  791                           else
  792                               return super.implementation(origin, types, checkResult);
  793                       }
  794                   };
  795                   return result;
  796               }
  797               if (m1SignatureMoreSpecific) return m1;
  798               if (m2SignatureMoreSpecific) return m2;
  799               return ambiguityError(m1, m2);
  800           case AMBIGUOUS:
  801               AmbiguityError e = (AmbiguityError)m2;
  802               Symbol err1 = mostSpecific(m1, e.sym, env, site, allowBoxing, useVarargs);
  803               Symbol err2 = mostSpecific(m1, e.sym2, env, site, allowBoxing, useVarargs);
  804               if (err1 == err2) return err1;
  805               if (err1 == e.sym && err2 == e.sym2) return m2;
  806               if (err1 instanceof AmbiguityError &&
  807                   err2 instanceof AmbiguityError &&
  808                   ((AmbiguityError)err1).sym == ((AmbiguityError)err2).sym)
  809                   return ambiguityError(m1, m2);
  810               else
  811                   return ambiguityError(err1, err2);
  812           default:
  813               throw new AssertionError();
  814           }
  815       }
  816       //where
  817       private boolean signatureMoreSpecific(Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) {
  818           noteWarner.clear();
  819           Type mtype1 = types.memberType(site, adjustVarargs(m1, m2, useVarargs));
  820           Type mtype2 = instantiate(env, site, adjustVarargs(m2, m1, useVarargs),
  821                   types.lowerBoundArgtypes(mtype1), null,
  822                   allowBoxing, false, noteWarner);
  823           return mtype2 != null &&
  824                   !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
  825       }
  826       //where
  827       private Symbol adjustVarargs(Symbol to, Symbol from, boolean useVarargs) {
  828           List<Type> fromArgs = from.type.getParameterTypes();
  829           List<Type> toArgs = to.type.getParameterTypes();
  830           if (useVarargs &&
  831                   (from.flags() & VARARGS) != 0 &&
  832                   (to.flags() & VARARGS) != 0) {
  833               Type varargsTypeFrom = fromArgs.last();
  834               Type varargsTypeTo = toArgs.last();
  835               ListBuffer<Type> args = ListBuffer.lb();
  836               if (toArgs.length() < fromArgs.length()) {
  837                   //if we are checking a varargs method 'from' against another varargs
  838                   //method 'to' (where arity of 'to' < arity of 'from') then expand signature
  839                   //of 'to' to 'fit' arity of 'from' (this means adding fake formals to 'to'
  840                   //until 'to' signature has the same arity as 'from')
  841                   while (fromArgs.head != varargsTypeFrom) {
  842                       args.append(toArgs.head == varargsTypeTo ? types.elemtype(varargsTypeTo) : toArgs.head);
  843                       fromArgs = fromArgs.tail;
  844                       toArgs = toArgs.head == varargsTypeTo ?
  845                           toArgs :
  846                           toArgs.tail;
  847                   }
  848               } else {
  849                   //formal argument list is same as original list where last
  850                   //argument (array type) is removed
  851                   args.appendList(toArgs.reverse().tail.reverse());
  852               }
  853               //append varargs element type as last synthetic formal
  854               args.append(types.elemtype(varargsTypeTo));
  855               Type mtype = types.createMethodTypeWithParameters(to.type, args.toList());
  856               return new MethodSymbol(to.flags_field & ~VARARGS, to.name, mtype, to.owner);
  857           } else {
  858               return to;
  859           }
  860       }
  861       //where
  862       Symbol ambiguityError(Symbol m1, Symbol m2) {
  863           if (((m1.flags() | m2.flags()) & CLASH) != 0) {
  864               return (m1.flags() & CLASH) == 0 ? m1 : m2;
  865           } else {
  866               return new AmbiguityError(m1, m2);
  867           }
  868       }
  869   
  870       /** Find best qualified method matching given name, type and value
  871        *  arguments.
  872        *  @param env       The current environment.
  873        *  @param site      The original type from where the selection
  874        *                   takes place.
  875        *  @param name      The method's name.
  876        *  @param argtypes  The method's value arguments.
  877        *  @param typeargtypes The method's type arguments
  878        *  @param allowBoxing Allow boxing conversions of arguments.
  879        *  @param useVarargs Box trailing arguments into an array for varargs.
  880        */
  881       Symbol findMethod(Env<AttrContext> env,
  882                         Type site,
  883                         Name name,
  884                         List<Type> argtypes,
  885                         List<Type> typeargtypes,
  886                         boolean allowBoxing,
  887                         boolean useVarargs,
  888                         boolean operator) {
  889           Symbol bestSoFar = methodNotFound;
  890           return findMethod(env,
  891                             site,
  892                             name,
  893                             argtypes,
  894                             typeargtypes,
  895                             site.tsym.type,
  896                             true,
  897                             bestSoFar,
  898                             allowBoxing,
  899                             useVarargs,
  900                             operator,
  901                             new HashSet<TypeSymbol>());
  902       }
  903       // where
  904       private Symbol findMethod(Env<AttrContext> env,
  905                                 Type site,
  906                                 Name name,
  907                                 List<Type> argtypes,
  908                                 List<Type> typeargtypes,
  909                                 Type intype,
  910                                 boolean abstractok,
  911                                 Symbol bestSoFar,
  912                                 boolean allowBoxing,
  913                                 boolean useVarargs,
  914                                 boolean operator,
  915                                 Set<TypeSymbol> seen) {
  916           for (Type ct = intype; ct.tag == CLASS || ct.tag == TYPEVAR; ct = types.supertype(ct)) {
  917               while (ct.tag == TYPEVAR)
  918                   ct = ct.getUpperBound();
  919               ClassSymbol c = (ClassSymbol)ct.tsym;
  920               if (!seen.add(c)) return bestSoFar;
  921               if ((c.flags() & (ABSTRACT | INTERFACE | ENUM)) == 0)
  922                   abstractok = false;
  923               for (Scope.Entry e = c.members().lookup(name);
  924                    e.scope != null;
  925                    e = e.next()) {
  926                   //- System.out.println(" e " + e.sym);
  927                   if (e.sym.kind == MTH &&
  928                       (e.sym.flags_field & SYNTHETIC) == 0) {
  929                       bestSoFar = selectBest(env, site, argtypes, typeargtypes,
  930                                              e.sym, bestSoFar,
  931                                              allowBoxing,
  932                                              useVarargs,
  933                                              operator);
  934                   }
  935               }
  936               if (name == names.init)
  937                   break;
  938               //- System.out.println(" - " + bestSoFar);
  939               if (abstractok) {
  940                   Symbol concrete = methodNotFound;
  941                   if ((bestSoFar.flags() & ABSTRACT) == 0)
  942                       concrete = bestSoFar;
  943                   for (List<Type> l = types.interfaces(c.type);
  944                        l.nonEmpty();
  945                        l = l.tail) {
  946                       bestSoFar = findMethod(env, site, name, argtypes,
  947                                              typeargtypes,
  948                                              l.head, abstractok, bestSoFar,
  949                                              allowBoxing, useVarargs, operator, seen);
  950                   }
  951                   if (concrete != bestSoFar &&
  952                       concrete.kind < ERR  && bestSoFar.kind < ERR &&
  953                       types.isSubSignature(concrete.type, bestSoFar.type))
  954                       bestSoFar = concrete;
  955               }
  956           }
  957           return bestSoFar;
  958       }
  959   
  960       /** Find unqualified method matching given name, type and value arguments.
  961        *  @param env       The current environment.
  962        *  @param name      The method's name.
  963        *  @param argtypes  The method's value arguments.
  964        *  @param typeargtypes  The method's type arguments.
  965        *  @param allowBoxing Allow boxing conversions of arguments.
  966        *  @param useVarargs Box trailing arguments into an array for varargs.
  967        */
  968       Symbol findFun(Env<AttrContext> env, Name name,
  969                      List<Type> argtypes, List<Type> typeargtypes,
  970                      boolean allowBoxing, boolean useVarargs) {
  971           Symbol bestSoFar = methodNotFound;
  972           Symbol sym;
  973           Env<AttrContext> env1 = env;
  974           boolean staticOnly = false;
  975           while (env1.outer != null) {
  976               if (isStatic(env1)) staticOnly = true;
  977               sym = findMethod(
  978                   env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
  979                   allowBoxing, useVarargs, false);
  980               if (sym.exists()) {
  981                   if (staticOnly &&
  982                       sym.kind == MTH &&
  983                       sym.owner.kind == TYP &&
  984                       (sym.flags() & STATIC) == 0) return new StaticError(sym);
  985                   else return sym;
  986               } else if (sym.kind < bestSoFar.kind) {
  987                   bestSoFar = sym;
  988               }
  989               if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
  990               env1 = env1.outer;
  991           }
  992   
  993           sym = findMethod(env, syms.predefClass.type, name, argtypes,
  994                            typeargtypes, allowBoxing, useVarargs, false);
  995           if (sym.exists())
  996               return sym;
  997   
  998           Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
  999           for (; e.scope != null; e = e.next()) {
 1000               sym = e.sym;
 1001               Type origin = e.getOrigin().owner.type;
 1002               if (sym.kind == MTH) {
 1003                   if (e.sym.owner.type != origin)
 1004                       sym = sym.clone(e.getOrigin().owner);
 1005                   if (!isAccessible(env, origin, sym))
 1006                       sym = new AccessError(env, origin, sym);
 1007                   bestSoFar = selectBest(env, origin,
 1008                                          argtypes, typeargtypes,
 1009                                          sym, bestSoFar,
 1010                                          allowBoxing, useVarargs, false);
 1011               }
 1012           }
 1013           if (bestSoFar.exists())
 1014               return bestSoFar;
 1015   
 1016           e = env.toplevel.starImportScope.lookup(name);
 1017           for (; e.scope != null; e = e.next()) {
 1018               sym = e.sym;
 1019               Type origin = e.getOrigin().owner.type;
 1020               if (sym.kind == MTH) {
 1021                   if (e.sym.owner.type != origin)
 1022                       sym = sym.clone(e.getOrigin().owner);
 1023                   if (!isAccessible(env, origin, sym))
 1024                       sym = new AccessError(env, origin, sym);
 1025                   bestSoFar = selectBest(env, origin,
 1026                                          argtypes, typeargtypes,
 1027                                          sym, bestSoFar,
 1028                                          allowBoxing, useVarargs, false);
 1029               }
 1030           }
 1031           return bestSoFar;
 1032       }
 1033   
 1034       /** Load toplevel or member class with given fully qualified name and
 1035        *  verify that it is accessible.
 1036        *  @param env       The current environment.
 1037        *  @param name      The fully qualified name of the class to be loaded.
 1038        */
 1039       Symbol loadClass(Env<AttrContext> env, Name name) {
 1040           try {
 1041               ClassSymbol c = reader.loadClass(name);
 1042               return isAccessible(env, c) ? c : new AccessError(c);
 1043           } catch (ClassReader.BadClassFile err) {
 1044               throw err;
 1045           } catch (CompletionFailure ex) {
 1046               return typeNotFound;
 1047           }
 1048       }
 1049   
 1050       /** Find qualified member type.
 1051        *  @param env       The current environment.
 1052        *  @param site      The original type from where the selection takes
 1053        *                   place.
 1054        *  @param name      The type's name.
 1055        *  @param c         The class to search for the member type. This is
 1056        *                   always a superclass or implemented interface of
 1057        *                   site's class.
 1058        */
 1059       Symbol findMemberType(Env<AttrContext> env,
 1060                             Type site,
 1061                             Name name,
 1062                             TypeSymbol c) {
 1063           Symbol bestSoFar = typeNotFound;
 1064           Symbol sym;
 1065           Scope.Entry e = c.members().lookup(name);
 1066           while (e.scope != null) {
 1067               if (e.sym.kind == TYP) {
 1068                   return isAccessible(env, site, e.sym)
 1069                       ? e.sym
 1070                       : new AccessError(env, site, e.sym);
 1071               }
 1072               e = e.next();
 1073           }
 1074           Type st = types.supertype(c.type);
 1075           if (st != null && st.tag == CLASS) {
 1076               sym = findMemberType(env, site, name, st.tsym);
 1077               if (sym.kind < bestSoFar.kind) bestSoFar = sym;
 1078           }
 1079           for (List<Type> l = types.interfaces(c.type);
 1080                bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
 1081                l = l.tail) {
 1082               sym = findMemberType(env, site, name, l.head.tsym);
 1083               if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&
 1084                   sym.owner != bestSoFar.owner)
 1085                   bestSoFar = new AmbiguityError(bestSoFar, sym);
 1086               else if (sym.kind < bestSoFar.kind)
 1087                   bestSoFar = sym;
 1088           }
 1089           return bestSoFar;
 1090       }
 1091   
 1092       /** Find a global type in given scope and load corresponding class.
 1093        *  @param env       The current environment.
 1094        *  @param scope     The scope in which to look for the type.
 1095        *  @param name      The type's name.
 1096        */
 1097       Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {
 1098           Symbol bestSoFar = typeNotFound;
 1099           for (Scope.Entry e = scope.lookup(name); e.scope != null; e = e.next()) {
 1100               Symbol sym = loadClass(env, e.sym.flatName());
 1101               if (bestSoFar.kind == TYP && sym.kind == TYP &&
 1102                   bestSoFar != sym)
 1103                   return new AmbiguityError(bestSoFar, sym);
 1104               else if (sym.kind < bestSoFar.kind)
 1105                   bestSoFar = sym;
 1106           }
 1107           return bestSoFar;
 1108       }
 1109   
 1110       /** Find an unqualified type symbol.
 1111        *  @param env       The current environment.
 1112        *  @param name      The type's name.
 1113        */
 1114       Symbol findType(Env<AttrContext> env, Name name) {
 1115           Symbol bestSoFar = typeNotFound;
 1116           Symbol sym;
 1117           boolean staticOnly = false;
 1118           for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {
 1119               if (isStatic(env1)) staticOnly = true;
 1120               for (Scope.Entry e = env1.info.scope.lookup(name);
 1121                    e.scope != null;
 1122                    e = e.next()) {
 1123                   if (e.sym.kind == TYP) {
 1124                       if (staticOnly &&
 1125                           e.sym.type.tag == TYPEVAR &&
 1126                           e.sym.owner.kind == TYP) return new StaticError(e.sym);
 1127                       return e.sym;
 1128                   }
 1129               }
 1130   
 1131               sym = findMemberType(env1, env1.enclClass.sym.type, name,
 1132                                    env1.enclClass.sym);
 1133               if (staticOnly && sym.kind == TYP &&
 1134                   sym.type.tag == CLASS &&
 1135                   sym.type.getEnclosingType().tag == CLASS &&
 1136                   env1.enclClass.sym.type.isParameterized() &&
 1137                   sym.type.getEnclosingType().isParameterized())
 1138                   return new StaticError(sym);
 1139               else if (sym.exists()) return sym;
 1140               else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
 1141   
 1142               JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass;
 1143               if ((encl.sym.flags() & STATIC) != 0)
 1144                   staticOnly = true;
 1145           }
 1146   
 1147           if (env.tree.getTag() != JCTree.IMPORT) {
 1148               sym = findGlobalType(env, env.toplevel.namedImportScope, name);
 1149               if (sym.exists()) return sym;
 1150               else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
 1151   
 1152               sym = findGlobalType(env, env.toplevel.packge.members(), name);
 1153               if (sym.exists()) return sym;
 1154               else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
 1155   
 1156               sym = findGlobalType(env, env.toplevel.starImportScope, name);
 1157               if (sym.exists()) return sym;
 1158               else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
 1159           }
 1160   
 1161           return bestSoFar;
 1162       }
 1163   
 1164       /** Find an unqualified identifier which matches a specified kind set.
 1165        *  @param env       The current environment.
 1166        *  @param name      The indentifier's name.
 1167        *  @param kind      Indicates the possible symbol kinds
 1168        *                   (a subset of VAL, TYP, PCK).
 1169        */
 1170       Symbol findIdent(Env<AttrContext> env, Name name, int kind) {
 1171           Symbol bestSoFar = typeNotFound;
 1172           Symbol sym;
 1173   
 1174           if ((kind & VAR) != 0) {
 1175               sym = findVar(env, name);
 1176               if (sym.exists()) return sym;
 1177               else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
 1178           }
 1179   
 1180           if ((kind & TYP) != 0) {
 1181               sym = findType(env, name);
 1182               if (sym.exists()) return sym;
 1183               else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
 1184           }
 1185   
 1186           if ((kind & PCK) != 0) return reader.enterPackage(name);
 1187           else return bestSoFar;
 1188       }
 1189   
 1190       /** Find an identifier in a package which matches a specified kind set.
 1191        *  @param env       The current environment.
 1192        *  @param name      The identifier's name.
 1193        *  @param kind      Indicates the possible symbol kinds
 1194        *                   (a nonempty subset of TYP, PCK).
 1195        */
 1196       Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck,
 1197                                 Name name, int kind) {
 1198           Name fullname = TypeSymbol.formFullName(name, pck);
 1199           Symbol bestSoFar = typeNotFound;
 1200           PackageSymbol pack = null;
 1201           if ((kind & PCK) != 0) {
 1202               pack = reader.enterPackage(fullname);
 1203               if (pack.exists()) return pack;
 1204           }
 1205           if ((kind & TYP) != 0) {
 1206               Symbol sym = loadClass(env, fullname);
 1207               if (sym.exists()) {
 1208                   // don't allow programs to use flatnames
 1209                   if (name == sym.name) return sym;
 1210               }
 1211               else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
 1212           }
 1213           return (pack != null) ? pack : bestSoFar;
 1214       }
 1215   
 1216       /** Find an identifier among the members of a given type `site'.
 1217        *  @param env       The current environment.
 1218        *  @param site      The type containing the symbol to be found.
 1219        *  @param name      The identifier's name.
 1220        *  @param kind      Indicates the possible symbol kinds
 1221        *                   (a subset of VAL, TYP).
 1222        */
 1223       Symbol findIdentInType(Env<AttrContext> env, Type site,
 1224                              Name name, int kind) {
 1225           Symbol bestSoFar = typeNotFound;
 1226           Symbol sym;
 1227           if ((kind & VAR) != 0) {
 1228               sym = findField(env, site, name, site.tsym);
 1229               if (sym.exists()) return sym;
 1230               else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
 1231           }
 1232   
 1233           if ((kind & TYP) != 0) {
 1234               sym = findMemberType(env, site, name, site.tsym);
 1235               if (sym.exists()) return sym;
 1236               else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
 1237           }
 1238           return bestSoFar;
 1239       }
 1240   
 1241   /* ***************************************************************************
 1242    *  Access checking
 1243    *  The following methods convert ResolveErrors to ErrorSymbols, issuing
 1244    *  an error message in the process
 1245    ****************************************************************************/
 1246   
 1247       /** If `sym' is a bad symbol: report error and return errSymbol
 1248        *  else pass through unchanged,
 1249        *  additional arguments duplicate what has been used in trying to find the
 1250        *  symbol (--> flyweight pattern). This improves performance since we
 1251        *  expect misses to happen frequently.
 1252        *
 1253        *  @param sym       The symbol that was found, or a ResolveError.
 1254        *  @param pos       The position to use for error reporting.
 1255        *  @param site      The original type from where the selection took place.
 1256        *  @param name      The symbol's name.
 1257        *  @param argtypes  The invocation's value arguments,
 1258        *                   if we looked for a method.
 1259        *  @param typeargtypes  The invocation's type arguments,
 1260        *                   if we looked for a method.
 1261        */
 1262       Symbol access(Symbol sym,
 1263                     DiagnosticPosition pos,
 1264                     Symbol location,
 1265                     Type site,
 1266                     Name name,
 1267                     boolean qualified,
 1268                     List<Type> argtypes,
 1269                     List<Type> typeargtypes) {
 1270           if (sym.kind >= AMBIGUOUS) {
 1271               ResolveError errSym = (ResolveError)sym;
 1272               if (!site.isErroneous() &&
 1273                   !Type.isErroneous(argtypes) &&
 1274                   (typeargtypes==null || !Type.isErroneous(typeargtypes)))
 1275                   logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes);
 1276               sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol);
 1277           }
 1278           return sym;
 1279       }
 1280   
 1281       /** Same as original access(), but without location.
 1282        */
 1283       Symbol access(Symbol sym,
 1284                     DiagnosticPosition pos,
 1285                     Type site,
 1286                     Name name,
 1287                     boolean qualified,
 1288                     List<Type> argtypes,
 1289                     List<Type> typeargtypes) {
 1290           return access(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes);
 1291       }
 1292   
 1293       /** Same as original access(), but without type arguments and arguments.
 1294        */
 1295       Symbol access(Symbol sym,
 1296                     DiagnosticPosition pos,
 1297                     Symbol location,
 1298                     Type site,
 1299                     Name name,
 1300                     boolean qualified) {
 1301           if (sym.kind >= AMBIGUOUS)
 1302               return access(sym, pos, location, site, name, qualified, List.<Type>nil(), null);
 1303           else
 1304               return sym;
 1305       }
 1306   
 1307       /** Same as original access(), but without location, type arguments and arguments.
 1308        */
 1309       Symbol access(Symbol sym,
 1310                     DiagnosticPosition pos,
 1311                     Type site,
 1312                     Name name,
 1313                     boolean qualified) {
 1314           return access(sym, pos, site.tsym, site, name, qualified);
 1315       }
 1316   
 1317       /** Check that sym is not an abstract method.
 1318        */
 1319       void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
 1320           if ((sym.flags() & ABSTRACT) != 0)
 1321               log.error(pos, "abstract.cant.be.accessed.directly",
 1322                         kindName(sym), sym, sym.location());
 1323       }
 1324   
 1325   /* ***************************************************************************
 1326    *  Debugging
 1327    ****************************************************************************/
 1328   
 1329       /** print all scopes starting with scope s and proceeding outwards.
 1330        *  used for debugging.
 1331        */
 1332       public void printscopes(Scope s) {
 1333           while (s != null) {
 1334               if (s.owner != null)
 1335                   System.err.print(s.owner + ": ");
 1336               for (Scope.Entry e = s.elems; e != null; e = e.sibling) {
 1337                   if ((e.sym.flags() & ABSTRACT) != 0)
 1338                       System.err.print("abstract ");
 1339                   System.err.print(e.sym + " ");
 1340               }
 1341               System.err.println();
 1342               s = s.next;
 1343           }
 1344       }
 1345   
 1346       void printscopes(Env<AttrContext> env) {
 1347           while (env.outer != null) {
 1348               System.err.println("------------------------------");
 1349               printscopes(env.info.scope);
 1350               env = env.outer;
 1351           }
 1352       }
 1353   
 1354       public void printscopes(Type t) {
 1355           while (t.tag == CLASS) {
 1356               printscopes(t.tsym.members());
 1357               t = types.supertype(t);
 1358           }
 1359       }
 1360   
 1361   /* ***************************************************************************
 1362    *  Name resolution
 1363    *  Naming conventions are as for symbol lookup
 1364    *  Unlike the find... methods these methods will report access errors
 1365    ****************************************************************************/
 1366   
 1367       /** Resolve an unqualified (non-method) identifier.
 1368        *  @param pos       The position to use for error reporting.
 1369        *  @param env       The environment current at the identifier use.
 1370        *  @param name      The identifier's name.
 1371        *  @param kind      The set of admissible symbol kinds for the identifier.
 1372        */
 1373       Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,
 1374                           Name name, int kind) {
 1375           return access(
 1376               findIdent(env, name, kind),
 1377               pos, env.enclClass.sym.type, name, false);
 1378       }
 1379   
 1380       /** Resolve an unqualified method identifier.
 1381        *  @param pos       The position to use for error reporting.
 1382        *  @param env       The environment current at the method invocation.
 1383        *  @param name      The identifier's name.
 1384        *  @param argtypes  The types of the invocation's value arguments.
 1385        *  @param typeargtypes  The types of the invocation's type arguments.
 1386        */
 1387       Symbol resolveMethod(DiagnosticPosition pos,
 1388                            Env<AttrContext> env,
 1389                            Name name,
 1390                            List<Type> argtypes,
 1391                            List<Type> typeargtypes) {
 1392           Symbol sym = startResolution();
 1393           List<MethodResolutionPhase> steps = methodResolutionSteps;
 1394           while (steps.nonEmpty() &&
 1395                  steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
 1396                  sym.kind >= ERRONEOUS) {
 1397               currentStep = steps.head;
 1398               sym = findFun(env, name, argtypes, typeargtypes,
 1399                       steps.head.isBoxingRequired,
 1400                       env.info.varArgs = steps.head.isVarargsRequired);
 1401               methodResolutionCache.put(steps.head, sym);
 1402               steps = steps.tail;
 1403           }
 1404           if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
 1405               MethodResolutionPhase errPhase =
 1406                       firstErroneousResolutionPhase();
 1407               sym = access(methodResolutionCache.get(errPhase),
 1408                       pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes);
 1409               env.info.varArgs = errPhase.isVarargsRequired;
 1410           }
 1411           return sym;
 1412       }
 1413   
 1414       private Symbol startResolution() {
 1415           wrongMethod.clear();
 1416           wrongMethods.clear();
 1417           return methodNotFound;
 1418       }
 1419   
 1420       /** Resolve a qualified method identifier
 1421        *  @param pos       The position to use for error reporting.
 1422        *  @param env       The environment current at the method invocation.
 1423        *  @param site      The type of the qualifying expression, in which
 1424        *                   identifier is searched.
 1425        *  @param name      The identifier's name.
 1426        *  @param argtypes  The types of the invocation's value arguments.
 1427        *  @param typeargtypes  The types of the invocation's type arguments.
 1428        */
 1429       Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
 1430                                     Type site, Name name, List<Type> argtypes,
 1431                                     List<Type> typeargtypes) {
 1432           return resolveQualifiedMethod(pos, env, site.tsym, site, name, argtypes, typeargtypes);
 1433       }
 1434       Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
 1435                                     Symbol location, Type site, Name name, List<Type> argtypes,
 1436                                     List<Type> typeargtypes) {
 1437           Symbol sym = startResolution();
 1438           List<MethodResolutionPhase> steps = methodResolutionSteps;
 1439           while (steps.nonEmpty() &&
 1440                  steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
 1441                  sym.kind >= ERRONEOUS) {
 1442               currentStep = steps.head;
 1443               sym = findMethod(env, site, name, argtypes, typeargtypes,
 1444                       steps.head.isBoxingRequired(),
 1445                       env.info.varArgs = steps.head.isVarargsRequired(), false);
 1446               methodResolutionCache.put(steps.head, sym);
 1447               steps = steps.tail;
 1448           }
 1449           if (sym.kind >= AMBIGUOUS) {
 1450               if (site.tsym.isPolymorphicSignatureGeneric()) {
 1451                   //polymorphic receiver - synthesize new method symbol
 1452                   env.info.varArgs = false;
 1453                   sym = findPolymorphicSignatureInstance(env,
 1454                           site, name, null, argtypes);
 1455               }
 1456               else {
 1457                   //if nothing is found return the 'first' error
 1458                   MethodResolutionPhase errPhase =
 1459                           firstErroneousResolutionPhase();
 1460                   sym = access(methodResolutionCache.get(errPhase),
 1461                           pos, location, site, name, true, argtypes, typeargtypes);
 1462                   env.info.varArgs = errPhase.isVarargsRequired;
 1463               }
 1464           } else if (allowMethodHandles && sym.isPolymorphicSignatureGeneric()) {
 1465               //non-instantiated polymorphic signature - synthesize new method symbol
 1466               env.info.varArgs = false;
 1467               sym = findPolymorphicSignatureInstance(env,
 1468                       site, name, (MethodSymbol)sym, argtypes);
 1469           }
 1470           return sym;
 1471       }
 1472   
 1473       /** Find or create an implicit method of exactly the given type (after erasure).
 1474        *  Searches in a side table, not the main scope of the site.
 1475        *  This emulates the lookup process required by JSR 292 in JVM.
 1476        *  @param env       Attribution environment
 1477        *  @param site      The original type from where the selection takes place.
 1478        *  @param name      The method's name.
 1479        *  @param spMethod  A template for the implicit method, or null.
 1480        *  @param argtypes  The required argument types.
 1481        *  @param typeargtypes  The required type arguments.
 1482        */
 1483       Symbol findPolymorphicSignatureInstance(Env<AttrContext> env, Type site,
 1484                                               Name name,
 1485                                               MethodSymbol spMethod,  // sig. poly. method or null if none
 1486                                               List<Type> argtypes) {
 1487           Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
 1488                   site, name, spMethod, argtypes);
 1489           long flags = ABSTRACT | HYPOTHETICAL | POLYMORPHIC_SIGNATURE |
 1490                       (spMethod != null ?
 1491                           spMethod.flags() & Flags.AccessFlags :
 1492                           Flags.PUBLIC | Flags.STATIC);
 1493           Symbol m = null;
 1494           for (Scope.Entry e = polymorphicSignatureScope.lookup(name);
 1495                e.scope != null;
 1496                e = e.next()) {
 1497               Symbol sym = e.sym;
 1498               if (types.isSameType(mtype, sym.type) &&
 1499                   (sym.flags() & Flags.STATIC) == (flags & Flags.STATIC) &&
 1500                   types.isSameType(sym.owner.type, site)) {
 1501                  m = sym;
 1502                  break;
 1503               }
 1504           }
 1505           if (m == null) {
 1506               // create the desired method
 1507               m = new MethodSymbol(flags, name, mtype, site.tsym);
 1508               polymorphicSignatureScope.enter(m);
 1509           }
 1510           return m;
 1511       }
 1512   
 1513       /** Resolve a qualified method identifier, throw a fatal error if not
 1514        *  found.
 1515        *  @param pos       The position to use for error reporting.
 1516        *  @param env       The environment current at the method invocation.
 1517        *  @param site      The type of the qualifying expression, in which
 1518        *                   identifier is searched.
 1519        *  @param name      The identifier's name.
 1520        *  @param argtypes  The types of the invocation's value arguments.
 1521        *  @param typeargtypes  The types of the invocation's type arguments.
 1522        */
 1523       public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env,
 1524                                           Type site, Name name,
 1525                                           List<Type> argtypes,
 1526                                           List<Type> typeargtypes) {
 1527           Symbol sym = resolveQualifiedMethod(
 1528               pos, env, site.tsym, site, name, argtypes, typeargtypes);
 1529           if (sym.kind == MTH) return (MethodSymbol)sym;
 1530           else throw new FatalError(
 1531                    diags.fragment("fatal.err.cant.locate.meth",
 1532                                   name));
 1533       }
 1534   
 1535       /** Resolve constructor.
 1536        *  @param pos       The position to use for error reporting.
 1537        *  @param env       The environment current at the constructor invocation.
 1538        *  @param site      The type of class for which a constructor is searched.
 1539        *  @param argtypes  The types of the constructor invocation's value
 1540        *                   arguments.
 1541        *  @param typeargtypes  The types of the constructor invocation's type
 1542        *                   arguments.
 1543        */
 1544       Symbol resolveConstructor(DiagnosticPosition pos,
 1545                                 Env<AttrContext> env,
 1546                                 Type site,
 1547                                 List<Type> argtypes,
 1548                                 List<Type> typeargtypes) {
 1549           Symbol sym = startResolution();
 1550           List<MethodResolutionPhase> steps = methodResolutionSteps;
 1551           while (steps.nonEmpty() &&
 1552                  steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
 1553                  sym.kind >= ERRONEOUS) {
 1554               currentStep = steps.head;
 1555               sym = resolveConstructor(pos, env, site, argtypes, typeargtypes,
 1556                       steps.head.isBoxingRequired(),
 1557                       env.info.varArgs = steps.head.isVarargsRequired());
 1558               methodResolutionCache.put(steps.head, sym);
 1559               steps = steps.tail;
 1560           }
 1561           if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
 1562               MethodResolutionPhase errPhase = firstErroneousResolutionPhase();
 1563               sym = access(methodResolutionCache.get(errPhase),
 1564                       pos, site, names.init, true, argtypes, typeargtypes);
 1565               env.info.varArgs = errPhase.isVarargsRequired();
 1566           }
 1567           return sym;
 1568       }
 1569   
 1570       /** Resolve constructor using diamond inference.
 1571        *  @param pos       The position to use for error reporting.
 1572        *  @param env       The environment current at the constructor invocation.
 1573        *  @param site      The type of class for which a constructor is searched.
 1574        *                   The scope of this class has been touched in attribution.
 1575        *  @param argtypes  The types of the constructor invocation's value
 1576        *                   arguments.
 1577        *  @param typeargtypes  The types of the constructor invocation's type
 1578        *                   arguments.
 1579        */
 1580       Symbol resolveDiamond(DiagnosticPosition pos,
 1581                                 Env<AttrContext> env,
 1582                                 Type site,
 1583                                 List<Type> argtypes,
 1584                                 List<Type> typeargtypes) {
 1585           Symbol sym = startResolution();
 1586           List<MethodResolutionPhase> steps = methodResolutionSteps;
 1587           while (steps.nonEmpty() &&
 1588                  steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
 1589                  sym.kind >= ERRONEOUS) {
 1590               currentStep = steps.head;
 1591               sym = resolveConstructor(pos, env, site, argtypes, typeargtypes,
 1592                       steps.head.isBoxingRequired(),
 1593                       env.info.varArgs = steps.head.isVarargsRequired());
 1594               methodResolutionCache.put(steps.head, sym);
 1595               steps = steps.tail;
 1596           }
 1597           if (sym.kind >= AMBIGUOUS) {
 1598               final JCDiagnostic details = sym.kind == WRONG_MTH ?
 1599                   ((InapplicableSymbolError)sym).explanation :
 1600                   null;
 1601               Symbol errSym = new ResolveError(WRONG_MTH, "diamond error") {
 1602                   @Override
 1603                   JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
 1604                           Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
 1605                       String key = details == null ?
 1606                           "cant.apply.diamond" :
 1607                           "cant.apply.diamond.1";
 1608                       return diags.create(dkind, log.currentSource(), pos, key,
 1609                               diags.fragment("diamond", site.tsym), details);
 1610                   }
 1611               };
 1612               MethodResolutionPhase errPhase = firstErroneousResolutionPhase();
 1613               sym = access(errSym, pos, site, names.init, true, argtypes, typeargtypes);
 1614               env.info.varArgs = errPhase.isVarargsRequired();
 1615           }
 1616           return sym;
 1617       }
 1618   
 1619       /** Resolve constructor.
 1620        *  @param pos       The position to use for error reporting.
 1621        *  @param env       The environment current at the constructor invocation.
 1622        *  @param site      The type of class for which a constructor is searched.
 1623        *  @param argtypes  The types of the constructor invocation's value
 1624        *                   arguments.
 1625        *  @param typeargtypes  The types of the constructor invocation's type
 1626        *                   arguments.
 1627        *  @param allowBoxing Allow boxing and varargs conversions.
 1628        *  @param useVarargs Box trailing arguments into an array for varargs.
 1629        */
 1630       Symbol resolveConstructor(DiagnosticPosition pos, Env<AttrContext> env,
 1631                                 Type site, List<Type> argtypes,
 1632                                 List<Type> typeargtypes,
 1633                                 boolean allowBoxing,
 1634                                 boolean useVarargs) {
 1635           Symbol sym = findMethod(env, site,
 1636                                   names.init, argtypes,
 1637                                   typeargtypes, allowBoxing,
 1638                                   useVarargs, false);
 1639           chk.checkDeprecated(pos, env.info.scope.owner, sym);
 1640           return sym;
 1641       }
 1642   
 1643       /** Resolve a constructor, throw a fatal error if not found.
 1644        *  @param pos       The position to use for error reporting.
 1645        *  @param env       The environment current at the method invocation.
 1646        *  @param site      The type to be constructed.
 1647        *  @param argtypes  The types of the invocation's value arguments.
 1648        *  @param typeargtypes  The types of the invocation's type arguments.
 1649        */
 1650       public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
 1651                                           Type site,
 1652                                           List<Type> argtypes,
 1653                                           List<Type> typeargtypes) {
 1654           Symbol sym = resolveConstructor(
 1655               pos, env, site, argtypes, typeargtypes);
 1656           if (sym.kind == MTH) return (MethodSymbol)sym;
 1657           else throw new FatalError(
 1658                    diags.fragment("fatal.err.cant.locate.ctor", site));
 1659       }
 1660   
 1661       /** Resolve operator.
 1662        *  @param pos       The position to use for error reporting.
 1663        *  @param optag     The tag of the operation tree.
 1664        *  @param env       The environment current at the operation.
 1665        *  @param argtypes  The types of the operands.
 1666        */
 1667       Symbol resolveOperator(DiagnosticPosition pos, int optag,
 1668                              Env<AttrContext> env, List<Type> argtypes) {
 1669           Name name = treeinfo.operatorName(optag);
 1670           Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
 1671                                   null, false, false, true);
 1672           if (boxingEnabled && sym.kind >= WRONG_MTHS)
 1673               sym = findMethod(env, syms.predefClass.type, name, argtypes,
 1674                                null, true, false, true);
 1675           return access(sym, pos, env.enclClass.sym.type, name,
 1676                         false, argtypes, null);
 1677       }
 1678   
 1679       /** Resolve operator.
 1680        *  @param pos       The position to use for error reporting.
 1681        *  @param optag     The tag of the operation tree.
 1682        *  @param env       The environment current at the operation.
 1683        *  @param arg       The type of the operand.
 1684        */
 1685       Symbol resolveUnaryOperator(DiagnosticPosition pos, int optag, Env<AttrContext> env, Type arg) {
 1686           return resolveOperator(pos, optag, env, List.of(arg));
 1687       }
 1688   
 1689       /** Resolve binary operator.
 1690        *  @param pos       The position to use for error reporting.
 1691        *  @param optag     The tag of the operation tree.
 1692        *  @param env       The environment current at the operation.
 1693        *  @param left      The types of the left operand.
 1694        *  @param right     The types of the right operand.
 1695        */
 1696       Symbol resolveBinaryOperator(DiagnosticPosition pos,
 1697                                    int optag,
 1698                                    Env<AttrContext> env,
 1699                                    Type left,
 1700                                    Type right) {
 1701           return resolveOperator(pos, optag, env, List.of(left, right));
 1702       }
 1703   
 1704       /**
 1705        * Resolve `c.name' where name == this or name == super.
 1706        * @param pos           The position to use for error reporting.
 1707        * @param env           The environment current at the expression.
 1708        * @param c             The qualifier.
 1709        * @param name          The identifier's name.
 1710        */
 1711       Symbol resolveSelf(DiagnosticPosition pos,
 1712                          Env<AttrContext> env,
 1713                          TypeSymbol c,
 1714                          Name name) {
 1715           Env<AttrContext> env1 = env;
 1716           boolean staticOnly = false;
 1717           while (env1.outer != null) {
 1718               if (isStatic(env1)) staticOnly = true;
 1719               if (env1.enclClass.sym == c) {
 1720                   Symbol sym = env1.info.scope.lookup(name).sym;
 1721                   if (sym != null) {
 1722                       if (staticOnly) sym = new StaticError(sym);
 1723                       return access(sym, pos, env.enclClass.sym.type,
 1724                                     name, true);
 1725                   }
 1726               }
 1727               if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
 1728               env1 = env1.outer;
 1729           }
 1730           log.error(pos, "not.encl.class", c);
 1731           return syms.errSymbol;
 1732       }
 1733   
 1734       /**
 1735        * Resolve `c.this' for an enclosing class c that contains the
 1736        * named member.
 1737        * @param pos           The position to use for error reporting.
 1738        * @param env           The environment current at the expression.
 1739        * @param member        The member that must be contained in the result.
 1740        */
 1741       Symbol resolveSelfContaining(DiagnosticPosition pos,
 1742                                    Env<AttrContext> env,
 1743                                    Symbol member,
 1744                                    boolean isSuperCall) {
 1745           Name name = names._this;
 1746           Env<AttrContext> env1 = isSuperCall ? env.outer : env;
 1747           boolean staticOnly = false;
 1748           if (env1 != null) {
 1749               while (env1 != null && env1.outer != null) {
 1750                   if (isStatic(env1)) staticOnly = true;
 1751                   if (env1.enclClass.sym.isSubClass(member.owner, types)) {
 1752                       Symbol sym = env1.info.scope.lookup(name).sym;
 1753                       if (sym != null) {
 1754                           if (staticOnly) sym = new StaticError(sym);
 1755                           return access(sym, pos, env.enclClass.sym.type,
 1756                                         name, true);
 1757                       }
 1758                   }
 1759                   if ((env1.enclClass.sym.flags() & STATIC) != 0)
 1760                       staticOnly = true;
 1761                   env1 = env1.outer;
 1762               }
 1763           }
 1764           log.error(pos, "encl.class.required", member);
 1765           return syms.errSymbol;
 1766       }
 1767   
 1768       /**
 1769        * Resolve an appropriate implicit this instance for t's container.
 1770        * JLS 8.8.5.1 and 15.9.2
 1771        */
 1772       Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) {
 1773           return resolveImplicitThis(pos, env, t, false);
 1774       }
 1775   
 1776       Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t, boolean isSuperCall) {
 1777           Type thisType = (((t.tsym.owner.kind & (MTH|VAR)) != 0)
 1778                            ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this)
 1779                            : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type;
 1780           if (env.info.isSelfCall && thisType.tsym == env.enclClass.sym)
 1781               log.error(pos, "cant.ref.before.ctor.called", "this");
 1782           return thisType;
 1783       }
 1784   
 1785   /* ***************************************************************************
 1786    *  ResolveError classes, indicating error situations when accessing symbols
 1787    ****************************************************************************/
 1788   
 1789       public void logAccessError(Env<AttrContext> env, JCTree tree, Type type) {
 1790           AccessError error = new AccessError(env, type.getEnclosingType(), type.tsym);
 1791           logResolveError(error, tree.pos(), type.getEnclosingType().tsym, type.getEnclosingType(), null, null, null);
 1792       }
 1793       //where
 1794       private void logResolveError(ResolveError error,
 1795               DiagnosticPosition pos,
 1796               Symbol location,
 1797               Type site,
 1798               Name name,
 1799               List<Type> argtypes,
 1800               List<Type> typeargtypes) {
 1801           JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
 1802                   pos, location, site, name, argtypes, typeargtypes);
 1803           if (d != null) {
 1804               d.setFlag(DiagnosticFlag.RESOLVE_ERROR);
 1805               log.report(d);
 1806           }
 1807       }
 1808   
 1809       private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
 1810   
 1811       public Object methodArguments(List<Type> argtypes) {
 1812           return argtypes.isEmpty() ? noArgs : argtypes;
 1813       }
 1814   
 1815       /**
 1816        * Root class for resolution errors. Subclass of ResolveError
 1817        * represent a different kinds of resolution error - as such they must
 1818        * specify how they map into concrete compiler diagnostics.
 1819        */
 1820       private abstract class ResolveError extends Symbol {
 1821   
 1822           /** The name of the kind of error, for debugging only. */
 1823           final String debugName;
 1824   
 1825           ResolveError(int kind, String debugName) {
 1826               super(kind, 0, null, null, null);
 1827               this.debugName = debugName;
 1828           }
 1829   
 1830           @Override
 1831           public <R, P> R accept(ElementVisitor<R, P> v, P p) {
 1832               throw new AssertionError();
 1833           }
 1834   
 1835           @Override
 1836           public String toString() {
 1837               return debugName;
 1838           }
 1839   
 1840           @Override
 1841           public boolean exists() {
 1842               return false;
 1843           }
 1844   
 1845           /**
 1846            * Create an external representation for this erroneous symbol to be
 1847            * used during attribution - by default this returns the symbol of a
 1848            * brand new error type which stores the original type found
 1849            * during resolution.
 1850            *
 1851            * @param name     the name used during resolution
 1852            * @param location the location from which the symbol is accessed
 1853            */
 1854           protected Symbol access(Name name, TypeSymbol location) {
 1855               return types.createErrorType(name, location, syms.errSymbol.type).tsym;
 1856           }
 1857   
 1858           /**
 1859            * Create a diagnostic representing this resolution error.
 1860            *
 1861            * @param dkind     The kind of the diagnostic to be created (e.g error).
 1862            * @param pos       The position to be used for error reporting.
 1863            * @param site      The original type from where the selection took place.
 1864            * @param name      The name of the symbol to be resolved.
 1865            * @param argtypes  The invocation's value arguments,
 1866            *                  if we looked for a method.
 1867            * @param typeargtypes  The invocation's type arguments,
 1868            *                      if we looked for a method.
 1869            */
 1870           abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
 1871                   DiagnosticPosition pos,
 1872                   Symbol location,
 1873                   Type site,
 1874                   Name name,
 1875                   List<Type> argtypes,
 1876                   List<Type> typeargtypes);
 1877   
 1878           /**
 1879            * A name designates an operator if it consists
 1880            * of a non-empty sequence of operator symbols +-~!/*%&|^<>=
 1881            */
 1882           boolean isOperator(Name name) {
 1883               int i = 0;
 1884               while (i < name.getByteLength() &&
 1885                      "+-~!*/%&|^<>=".indexOf(name.getByteAt(i)) >= 0) i++;
 1886               return i > 0 && i == name.getByteLength();
 1887           }
 1888       }
 1889   
 1890       /**
 1891        * This class is the root class of all resolution errors caused by
 1892        * an invalid symbol being found during resolution.
 1893        */
 1894       abstract class InvalidSymbolError extends ResolveError {
 1895   
 1896           /** The invalid symbol found during resolution */
 1897           Symbol sym;
 1898   
 1899           InvalidSymbolError(int kind, Symbol sym, String debugName) {
 1900               super(kind, debugName);
 1901               this.sym = sym;
 1902           }
 1903   
 1904           @Override
 1905           public boolean exists() {
 1906               return true;
 1907           }
 1908   
 1909           @Override
 1910           public String toString() {
 1911                return super.toString() + " wrongSym=" + sym;
 1912           }
 1913   
 1914           @Override
 1915           public Symbol access(Name name, TypeSymbol location) {
 1916               if (sym.kind >= AMBIGUOUS)
 1917                   return ((ResolveError)sym).access(name, location);
 1918               else if ((sym.kind & ERRONEOUS) == 0 && (sym.kind & TYP) != 0)
 1919                   return types.createErrorType(name, location, sym.type).tsym;
 1920               else
 1921                   return sym;
 1922           }
 1923       }
 1924   
 1925       /**
 1926        * InvalidSymbolError error class indicating that a symbol matching a
 1927        * given name does not exists in a given site.
 1928        */
 1929       class SymbolNotFoundError extends ResolveError {
 1930   
 1931           SymbolNotFoundError(int kind) {
 1932               super(kind, "symbol not found error");
 1933           }
 1934   
 1935           @Override
 1936           JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
 1937                   DiagnosticPosition pos,
 1938                   Symbol location,
 1939                   Type site,
 1940                   Name name,
 1941                   List<Type> argtypes,
 1942                   List<Type> typeargtypes) {
 1943               argtypes = argtypes == null ? List.<Type>nil() : argtypes;
 1944               typeargtypes = typeargtypes == null ? List.<Type>nil() : typeargtypes;
 1945               if (name == names.error)
 1946                   return null;
 1947   
 1948               if (isOperator(name)) {
 1949                   boolean isUnaryOp = argtypes.size() == 1;
 1950                   String key = argtypes.size() == 1 ?
 1951                       "operator.cant.be.applied" :
 1952                       "operator.cant.be.applied.1";
 1953                   Type first = argtypes.head;
 1954                   Type second = !isUnaryOp ? argtypes.tail.head : null;
 1955                   return diags.create(dkind, log.currentSource(), pos,
 1956                           key, name, first, second);
 1957               }
 1958               boolean hasLocation = false;
 1959               if (location == null) {
 1960                   location = site.tsym;
 1961               }
 1962               if (!location.name.isEmpty()) {
 1963                   if (location.kind == PCK && !site.tsym.exists()) {
 1964                       return diags.create(dkind, log.currentSource(), pos,
 1965                           "doesnt.exist", location);
 1966                   }
 1967                   hasLocation = !location.name.equals(names._this) &&
 1968                           !location.name.equals(names._super);
 1969               }
 1970               boolean isConstructor = kind == ABSENT_MTH &&
 1971                       name == names.table.names.init;
 1972               KindName kindname = isConstructor ? KindName.CONSTRUCTOR : absentKind(kind);
 1973               Name idname = isConstructor ? site.tsym.name : name;
 1974               String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
 1975               if (hasLocation) {
 1976                   return diags.create(dkind, log.currentSource(), pos,
 1977                           errKey, kindname, idname, //symbol kindname, name
 1978                           typeargtypes, argtypes, //type parameters and arguments (if any)
 1979                           getLocationDiag(location, site)); //location kindname, type
 1980               }
 1981               else {
 1982                   return diags.create(dkind, log.currentSource(), pos,
 1983                           errKey, kindname, idname, //symbol kindname, name
 1984                           typeargtypes, argtypes); //type parameters and arguments (if any)
 1985               }
 1986           }
 1987           //where
 1988           private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) {
 1989               String key = "cant.resolve";
 1990               String suffix = hasLocation ? ".location" : "";
 1991               switch (kindname) {
 1992                   case METHOD:
 1993                   case CONSTRUCTOR: {
 1994                       suffix += ".args";
 1995                       suffix += hasTypeArgs ? ".params" : "";
 1996                   }
 1997               }
 1998               return key + suffix;
 1999           }
 2000           private JCDiagnostic getLocationDiag(Symbol location, Type site) {
 2001               if (location.kind == VAR) {
 2002                   return diags.fragment("location.1",
 2003                       kindName(location),
 2004                       location,
 2005                       location.type);
 2006               } else {
 2007                   return diags.fragment("location",
 2008                       typeKindName(site),
 2009                       site,
 2010                       null);
 2011               }
 2012           }
 2013       }
 2014   
 2015       /**
 2016        * InvalidSymbolError error class indicating that a given symbol
 2017        * (either a method, a constructor or an operand) is not applicable
 2018        * given an actual arguments/type argument list.
 2019        */
 2020       class InapplicableSymbolError extends InvalidSymbolError {
 2021   
 2022           /** An auxiliary explanation set in case of instantiation errors. */
 2023           JCDiagnostic explanation;
 2024   
 2025           InapplicableSymbolError(Symbol sym) {
 2026               super(WRONG_MTH, sym, "inapplicable symbol error");
 2027           }
 2028   
 2029           /** Update sym and explanation and return this.
 2030            */
 2031           InapplicableSymbolError setWrongSym(Symbol sym, JCDiagnostic explanation) {
 2032               this.sym = sym;
 2033               if (this.sym == sym && explanation != null)
 2034                   this.explanation = explanation; //update the details
 2035               return this;
 2036           }
 2037   
 2038           /** Update sym and return this.
 2039            */
 2040           InapplicableSymbolError setWrongSym(Symbol sym) {
 2041               this.sym = sym;
 2042               return this;
 2043           }
 2044   
 2045           @Override
 2046           public String toString() {
 2047               return super.toString() + " explanation=" + explanation;
 2048           }
 2049   
 2050           @Override
 2051           JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
 2052                   DiagnosticPosition pos,
 2053                   Symbol location,
 2054                   Type site,
 2055                   Name name,
 2056                   List<Type> argtypes,
 2057                   List<Type> typeargtypes) {
 2058               if (name == names.error)
 2059                   return null;
 2060   
 2061               if (isOperator(name)) {
 2062                   boolean isUnaryOp = argtypes.size() == 1;
 2063                   String key = argtypes.size() == 1 ?
 2064                       "operator.cant.be.applied" :
 2065                       "operator.cant.be.applied.1";
 2066                   Type first = argtypes.head;
 2067                   Type second = !isUnaryOp ? argtypes.tail.head : null;
 2068                   return diags.create(dkind, log.currentSource(), pos,
 2069                           key, name, first, second);
 2070               }
 2071               else {
 2072                   Symbol ws = sym.asMemberOf(site, types);
 2073                   return diags.create(dkind, log.currentSource(), pos,
 2074                             "cant.apply.symbol" + (explanation != null ? ".1" : ""),
 2075                             kindName(ws),
 2076                             ws.name == names.init ? ws.owner.name : ws.name,
 2077                             methodArguments(ws.type.getParameterTypes()),
 2078                             methodArguments(argtypes),
 2079                             kindName(ws.owner),
 2080                             ws.owner.type,
 2081                             explanation);
 2082               }
 2083           }
 2084   
 2085           void clear() {
 2086               explanation = null;
 2087           }
 2088   
 2089           @Override
 2090           public Symbol access(Name name, TypeSymbol location) {
 2091               return types.createErrorType(name, location, syms.errSymbol.type).tsym;
 2092           }
 2093       }
 2094   
 2095       /**
 2096        * ResolveError error class indicating that a set of symbols
 2097        * (either methods, constructors or operands) is not applicable
 2098        * given an actual arguments/type argument list.
 2099        */
 2100       class InapplicableSymbolsError extends ResolveError {
 2101   
 2102           private List<Candidate> candidates = List.nil();
 2103   
 2104           InapplicableSymbolsError(Symbol sym) {
 2105               super(WRONG_MTHS, "inapplicable symbols");
 2106           }
 2107   
 2108           @Override
 2109           JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
 2110                   DiagnosticPosition pos,
 2111                   Symbol location,
 2112                   Type site,
 2113                   Name name,
 2114                   List<Type> argtypes,
 2115                   List<Type> typeargtypes) {
 2116               if (candidates.nonEmpty()) {
 2117                   JCDiagnostic err = diags.create(dkind,
 2118                           log.currentSource(),
 2119                           pos,
 2120                           "cant.apply.symbols",
 2121                           name == names.init ? KindName.CONSTRUCTOR : absentKind(kind),
 2122                           getName(),
 2123                           argtypes);
 2124                   return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site));
 2125               } else {
 2126                   return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
 2127                       location, site, name, argtypes, typeargtypes);
 2128               }
 2129           }
 2130   
 2131           //where
 2132           List<JCDiagnostic> candidateDetails(Type site) {
 2133               List<JCDiagnostic> details = List.nil();
 2134               for (Candidate c : candidates)
 2135                   details = details.prepend(c.getDiagnostic(site));
 2136               return details.reverse();
 2137           }
 2138   
 2139           Symbol addCandidate(MethodResolutionPhase currentStep, Symbol sym, JCDiagnostic details) {
 2140               Candidate c = new Candidate(currentStep, sym, details);
 2141               if (c.isValid() && !candidates.contains(c))
 2142                   candidates = candidates.append(c);
 2143               return this;
 2144           }
 2145   
 2146           void clear() {
 2147               candidates = List.nil();
 2148           }
 2149   
 2150           private Name getName() {
 2151               Symbol sym = candidates.head.sym;
 2152               return sym.name == names.init ?
 2153                   sym.owner.name :
 2154                   sym.name;
 2155           }
 2156   
 2157           private class Candidate {
 2158   
 2159               final MethodResolutionPhase step;
 2160               final Symbol sym;
 2161               final JCDiagnostic details;
 2162   
 2163               private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details) {
 2164                   this.step = step;
 2165                   this.sym = sym;
 2166                   this.details = details;
 2167               }
 2168   
 2169               JCDiagnostic getDiagnostic(Type site) {
 2170                   return diags.fragment("inapplicable.method",
 2171                           Kinds.kindName(sym),
 2172                           sym.location(site, types),
 2173                           sym.asMemberOf(site, types),
 2174                           details);
 2175               }
 2176   
 2177               @Override
 2178               public boolean equals(Object o) {
 2179                   if (o instanceof Candidate) {
 2180                       Symbol s1 = this.sym;
 2181                       Symbol s2 = ((Candidate)o).sym;
 2182                       if  ((s1 != s2 &&
 2183                           (s1.overrides(s2, s1.owner.type.tsym, types, false) ||
 2184                           (s2.overrides(s1, s2.owner.type.tsym, types, false)))) ||
 2185                           ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner))
 2186                           return true;
 2187                   }
 2188                   return false;
 2189               }
 2190   
 2191               boolean isValid() {
 2192                   return  (((sym.flags() & VARARGS) != 0 && step == VARARITY) ||
 2193                             (sym.flags() & VARARGS) == 0 && step == (boxingEnabled ? BOX : BASIC));
 2194               }
 2195           }
 2196       }
 2197   
 2198       /**
 2199        * An InvalidSymbolError error class indicating that a symbol is not
 2200        * accessible from a given site
 2201        */
 2202       class AccessError extends InvalidSymbolError {
 2203   
 2204           private Env<AttrContext> env;
 2205           private Type site;
 2206   
 2207           AccessError(Symbol sym) {
 2208               this(null, null, sym);
 2209           }
 2210   
 2211           AccessError(Env<AttrContext> env, Type site, Symbol sym) {
 2212               super(HIDDEN, sym, "access error");
 2213               this.env = env;
 2214               this.site = site;
 2215               if (debugResolve)
 2216                   log.error("proc.messager", sym + " @ " + site + " is inaccessible.");
 2217           }
 2218   
 2219           @Override
 2220           public boolean exists() {
 2221               return false;
 2222           }
 2223   
 2224           @Override
 2225           JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
 2226                   DiagnosticPosition pos,
 2227                   Symbol location,
 2228                   Type site,
 2229                   Name name,
 2230                   List<Type> argtypes,
 2231                   List<Type> typeargtypes) {
 2232               if (sym.owner.type.tag == ERROR)
 2233                   return null;
 2234   
 2235               if (sym.name == names.init && sym.owner != site.tsym) {
 2236                   return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind,
 2237                           pos, location, site, name, argtypes, typeargtypes);
 2238               }
 2239               else if ((sym.flags() & PUBLIC) != 0
 2240                   || (env != null && this.site != null
 2241                       && !isAccessible(env, this.site))) {
 2242                   return diags.create(dkind, log.currentSource(),
 2243                           pos, "not.def.access.class.intf.cant.access",
 2244                       sym, sym.location());
 2245               }
 2246               else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) {
 2247                   return diags.create(dkind, log.currentSource(),
 2248                           pos, "report.access", sym,
 2249                           asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
 2250                           sym.location());
 2251               }
 2252               else {
 2253                   return diags.create(dkind, log.currentSource(),
 2254                           pos, "not.def.public.cant.access", sym, sym.location());
 2255               }
 2256           }
 2257       }
 2258   
 2259       /**
 2260        * InvalidSymbolError error class indicating that an instance member
 2261        * has erroneously been accessed from a static context.
 2262        */
 2263       class StaticError extends InvalidSymbolError {
 2264   
 2265           StaticError(Symbol sym) {
 2266               super(STATICERR, sym, "static error");
 2267           }
 2268   
 2269           @Override
 2270           JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
 2271                   DiagnosticPosition pos,
 2272                   Symbol location,
 2273                   Type site,
 2274                   Name name,
 2275                   List<Type> argtypes,
 2276                   List<Type> typeargtypes) {
 2277               Symbol errSym = ((sym.kind == TYP && sym.type.tag == CLASS)
 2278                   ? types.erasure(sym.type).tsym
 2279                   : sym);
 2280               return diags.create(dkind, log.currentSource(), pos,
 2281                       "non-static.cant.be.ref", kindName(sym), errSym);
 2282           }
 2283       }
 2284   
 2285       /**
 2286        * InvalidSymbolError error class indicating that a pair of symbols
 2287        * (either methods, constructors or operands) are ambiguous
 2288        * given an actual arguments/type argument list.
 2289        */
 2290       class AmbiguityError extends InvalidSymbolError {
 2291   
 2292           /** The other maximally specific symbol */
 2293           Symbol sym2;
 2294   
 2295           AmbiguityError(Symbol sym1, Symbol sym2) {
 2296               super(AMBIGUOUS, sym1, "ambiguity error");
 2297               this.sym2 = sym2;
 2298           }
 2299   
 2300           @Override
 2301           JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
 2302                   DiagnosticPosition pos,
 2303                   Symbol location,
 2304                   Type site,
 2305                   Name name,
 2306                   List<Type> argtypes,
 2307                   List<Type> typeargtypes) {
 2308               AmbiguityError pair = this;
 2309               while (true) {
 2310                   if (pair.sym.kind == AMBIGUOUS)
 2311                       pair = (AmbiguityError)pair.sym;
 2312                   else if (pair.sym2.kind == AMBIGUOUS)
 2313                       pair = (AmbiguityError)pair.sym2;
 2314                   else break;
 2315               }
 2316               Name sname = pair.sym.name;
 2317               if (sname == names.init) sname = pair.sym.owner.name;
 2318               return diags.create(dkind, log.currentSource(),
 2319                         pos, "ref.ambiguous", sname,
 2320                         kindName(pair.sym),
 2321                         pair.sym,
 2322                         pair.sym.location(site, types),
 2323                         kindName(pair.sym2),
 2324                         pair.sym2,
 2325                         pair.sym2.location(site, types));
 2326           }
 2327       }
 2328   
 2329       enum MethodResolutionPhase {
 2330           BASIC(false, false),
 2331           BOX(true, false),
 2332           VARARITY(true, true);
 2333   
 2334           boolean isBoxingRequired;
 2335           boolean isVarargsRequired;
 2336   
 2337           MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) {
 2338              this.isBoxingRequired = isBoxingRequired;
 2339              this.isVarargsRequired = isVarargsRequired;
 2340           }
 2341   
 2342           public boolean isBoxingRequired() {
 2343               return isBoxingRequired;
 2344           }
 2345   
 2346           public boolean isVarargsRequired() {
 2347               return isVarargsRequired;
 2348           }
 2349   
 2350           public boolean isApplicable(boolean boxingEnabled, boolean varargsEnabled) {
 2351               return (varargsEnabled || !isVarargsRequired) &&
 2352                      (boxingEnabled || !isBoxingRequired);
 2353           }
 2354       }
 2355   
 2356       private Map<MethodResolutionPhase, Symbol> methodResolutionCache =
 2357           new HashMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.values().length);
 2358   
 2359       final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
 2360   
 2361       private MethodResolutionPhase currentStep = null;
 2362   
 2363       private MethodResolutionPhase firstErroneousResolutionPhase() {
 2364           MethodResolutionPhase bestSoFar = BASIC;
 2365           Symbol sym = methodNotFound;
 2366           List<MethodResolutionPhase> steps = methodResolutionSteps;
 2367           while (steps.nonEmpty() &&
 2368                  steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
 2369                  sym.kind >= WRONG_MTHS) {
 2370               sym = methodResolutionCache.get(steps.head);
 2371               bestSoFar = steps.head;
 2372               steps = steps.tail;
 2373           }
 2374           return bestSoFar;
 2375       }
 2376   }

Home » openjdk-7 » com.sun.tools » javac » comp » [javadoc | source]