src/share/classes/com/sun/tools/javac/comp/Resolve.java

changeset 1
9a66ca7c79fa
child 19
adaa3fc51b60
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Sat Dec 01 00:00:00 2007 +0000
     1.3 @@ -0,0 +1,1809 @@
     1.4 +/*
     1.5 + * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.  Sun designates this
    1.11 + * particular file as subject to the "Classpath" exception as provided
    1.12 + * by Sun in the LICENSE file that accompanied this code.
    1.13 + *
    1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.17 + * version 2 for more details (a copy is included in the LICENSE file that
    1.18 + * accompanied this code).
    1.19 + *
    1.20 + * You should have received a copy of the GNU General Public License version
    1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.23 + *
    1.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    1.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
    1.26 + * have any questions.
    1.27 + */
    1.28 +
    1.29 +package com.sun.tools.javac.comp;
    1.30 +
    1.31 +import com.sun.tools.javac.util.*;
    1.32 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    1.33 +import com.sun.tools.javac.code.*;
    1.34 +import com.sun.tools.javac.jvm.*;
    1.35 +import com.sun.tools.javac.tree.*;
    1.36 +
    1.37 +import com.sun.tools.javac.code.Type.*;
    1.38 +import com.sun.tools.javac.code.Symbol.*;
    1.39 +import com.sun.tools.javac.tree.JCTree.*;
    1.40 +
    1.41 +import static com.sun.tools.javac.code.Flags.*;
    1.42 +import static com.sun.tools.javac.code.Kinds.*;
    1.43 +import static com.sun.tools.javac.code.TypeTags.*;
    1.44 +import javax.lang.model.element.ElementVisitor;
    1.45 +
    1.46 +/** Helper class for name resolution, used mostly by the attribution phase.
    1.47 + *
    1.48 + *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
    1.49 + *  you write code that depends on this, you do so at your own risk.
    1.50 + *  This code and its internal interfaces are subject to change or
    1.51 + *  deletion without notice.</b>
    1.52 + */
    1.53 +public class Resolve {
    1.54 +    protected static final Context.Key<Resolve> resolveKey =
    1.55 +        new Context.Key<Resolve>();
    1.56 +
    1.57 +    Name.Table names;
    1.58 +    Log log;
    1.59 +    Symtab syms;
    1.60 +    Check chk;
    1.61 +    Infer infer;
    1.62 +    ClassReader reader;
    1.63 +    TreeInfo treeinfo;
    1.64 +    Types types;
    1.65 +    public final boolean boxingEnabled; // = source.allowBoxing();
    1.66 +    public final boolean varargsEnabled; // = source.allowVarargs();
    1.67 +    private final boolean debugResolve;
    1.68 +
    1.69 +    public static Resolve instance(Context context) {
    1.70 +        Resolve instance = context.get(resolveKey);
    1.71 +        if (instance == null)
    1.72 +            instance = new Resolve(context);
    1.73 +        return instance;
    1.74 +    }
    1.75 +
    1.76 +    protected Resolve(Context context) {
    1.77 +        context.put(resolveKey, this);
    1.78 +        syms = Symtab.instance(context);
    1.79 +
    1.80 +        varNotFound = new
    1.81 +            ResolveError(ABSENT_VAR, syms.errSymbol, "variable not found");
    1.82 +        wrongMethod = new
    1.83 +            ResolveError(WRONG_MTH, syms.errSymbol, "method not found");
    1.84 +        wrongMethods = new
    1.85 +            ResolveError(WRONG_MTHS, syms.errSymbol, "wrong methods");
    1.86 +        methodNotFound = new
    1.87 +            ResolveError(ABSENT_MTH, syms.errSymbol, "method not found");
    1.88 +        typeNotFound = new
    1.89 +            ResolveError(ABSENT_TYP, syms.errSymbol, "type not found");
    1.90 +
    1.91 +        names = Name.Table.instance(context);
    1.92 +        log = Log.instance(context);
    1.93 +        chk = Check.instance(context);
    1.94 +        infer = Infer.instance(context);
    1.95 +        reader = ClassReader.instance(context);
    1.96 +        treeinfo = TreeInfo.instance(context);
    1.97 +        types = Types.instance(context);
    1.98 +        Source source = Source.instance(context);
    1.99 +        boxingEnabled = source.allowBoxing();
   1.100 +        varargsEnabled = source.allowVarargs();
   1.101 +        Options options = Options.instance(context);
   1.102 +        debugResolve = options.get("debugresolve") != null;
   1.103 +    }
   1.104 +
   1.105 +    /** error symbols, which are returned when resolution fails
   1.106 +     */
   1.107 +    final ResolveError varNotFound;
   1.108 +    final ResolveError wrongMethod;
   1.109 +    final ResolveError wrongMethods;
   1.110 +    final ResolveError methodNotFound;
   1.111 +    final ResolveError typeNotFound;
   1.112 +
   1.113 +/* ************************************************************************
   1.114 + * Identifier resolution
   1.115 + *************************************************************************/
   1.116 +
   1.117 +    /** An environment is "static" if its static level is greater than
   1.118 +     *  the one of its outer environment
   1.119 +     */
   1.120 +    static boolean isStatic(Env<AttrContext> env) {
   1.121 +        return env.info.staticLevel > env.outer.info.staticLevel;
   1.122 +    }
   1.123 +
   1.124 +    /** An environment is an "initializer" if it is a constructor or
   1.125 +     *  an instance initializer.
   1.126 +     */
   1.127 +    static boolean isInitializer(Env<AttrContext> env) {
   1.128 +        Symbol owner = env.info.scope.owner;
   1.129 +        return owner.isConstructor() ||
   1.130 +            owner.owner.kind == TYP &&
   1.131 +            (owner.kind == VAR ||
   1.132 +             owner.kind == MTH && (owner.flags() & BLOCK) != 0) &&
   1.133 +            (owner.flags() & STATIC) == 0;
   1.134 +    }
   1.135 +
   1.136 +    /** Is class accessible in given evironment?
   1.137 +     *  @param env    The current environment.
   1.138 +     *  @param c      The class whose accessibility is checked.
   1.139 +     */
   1.140 +    public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) {
   1.141 +        switch ((short)(c.flags() & AccessFlags)) {
   1.142 +        case PRIVATE:
   1.143 +            return
   1.144 +                env.enclClass.sym.outermostClass() ==
   1.145 +                c.owner.outermostClass();
   1.146 +        case 0:
   1.147 +            return
   1.148 +                env.toplevel.packge == c.owner // fast special case
   1.149 +                ||
   1.150 +                env.toplevel.packge == c.packge()
   1.151 +                ||
   1.152 +                // Hack: this case is added since synthesized default constructors
   1.153 +                // of anonymous classes should be allowed to access
   1.154 +                // classes which would be inaccessible otherwise.
   1.155 +                env.enclMethod != null &&
   1.156 +                (env.enclMethod.mods.flags & ANONCONSTR) != 0;
   1.157 +        default: // error recovery
   1.158 +        case PUBLIC:
   1.159 +            return true;
   1.160 +        case PROTECTED:
   1.161 +            return
   1.162 +                env.toplevel.packge == c.owner // fast special case
   1.163 +                ||
   1.164 +                env.toplevel.packge == c.packge()
   1.165 +                ||
   1.166 +                isInnerSubClass(env.enclClass.sym, c.owner);
   1.167 +        }
   1.168 +    }
   1.169 +    //where
   1.170 +        /** Is given class a subclass of given base class, or an inner class
   1.171 +         *  of a subclass?
   1.172 +         *  Return null if no such class exists.
   1.173 +         *  @param c     The class which is the subclass or is contained in it.
   1.174 +         *  @param base  The base class
   1.175 +         */
   1.176 +        private boolean isInnerSubClass(ClassSymbol c, Symbol base) {
   1.177 +            while (c != null && !c.isSubClass(base, types)) {
   1.178 +                c = c.owner.enclClass();
   1.179 +            }
   1.180 +            return c != null;
   1.181 +        }
   1.182 +
   1.183 +    boolean isAccessible(Env<AttrContext> env, Type t) {
   1.184 +        return (t.tag == ARRAY)
   1.185 +            ? isAccessible(env, types.elemtype(t))
   1.186 +            : isAccessible(env, t.tsym);
   1.187 +    }
   1.188 +
   1.189 +    /** Is symbol accessible as a member of given type in given evironment?
   1.190 +     *  @param env    The current environment.
   1.191 +     *  @param site   The type of which the tested symbol is regarded
   1.192 +     *                as a member.
   1.193 +     *  @param sym    The symbol.
   1.194 +     */
   1.195 +    public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) {
   1.196 +        if (sym.name == names.init && sym.owner != site.tsym) return false;
   1.197 +        ClassSymbol sub;
   1.198 +        switch ((short)(sym.flags() & AccessFlags)) {
   1.199 +        case PRIVATE:
   1.200 +            return
   1.201 +                (env.enclClass.sym == sym.owner // fast special case
   1.202 +                 ||
   1.203 +                 env.enclClass.sym.outermostClass() ==
   1.204 +                 sym.owner.outermostClass())
   1.205 +                &&
   1.206 +                sym.isInheritedIn(site.tsym, types);
   1.207 +        case 0:
   1.208 +            return
   1.209 +                (env.toplevel.packge == sym.owner.owner // fast special case
   1.210 +                 ||
   1.211 +                 env.toplevel.packge == sym.packge())
   1.212 +                &&
   1.213 +                isAccessible(env, site)
   1.214 +                &&
   1.215 +                sym.isInheritedIn(site.tsym, types);
   1.216 +        case PROTECTED:
   1.217 +            return
   1.218 +                (env.toplevel.packge == sym.owner.owner // fast special case
   1.219 +                 ||
   1.220 +                 env.toplevel.packge == sym.packge()
   1.221 +                 ||
   1.222 +                 isProtectedAccessible(sym, env.enclClass.sym, site)
   1.223 +                 ||
   1.224 +                 // OK to select instance method or field from 'super' or type name
   1.225 +                 // (but type names should be disallowed elsewhere!)
   1.226 +                 env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP)
   1.227 +                &&
   1.228 +                isAccessible(env, site)
   1.229 +                &&
   1.230 +                // `sym' is accessible only if not overridden by
   1.231 +                // another symbol which is a member of `site'
   1.232 +                // (because, if it is overridden, `sym' is not strictly
   1.233 +                // speaking a member of `site'.)
   1.234 +                (sym.kind != MTH || sym.isConstructor() ||
   1.235 +                 ((MethodSymbol)sym).implementation(site.tsym, types, true) == sym);
   1.236 +        default: // this case includes erroneous combinations as well
   1.237 +            return isAccessible(env, site);
   1.238 +        }
   1.239 +    }
   1.240 +    //where
   1.241 +        /** Is given protected symbol accessible if it is selected from given site
   1.242 +         *  and the selection takes place in given class?
   1.243 +         *  @param sym     The symbol with protected access
   1.244 +         *  @param c       The class where the access takes place
   1.245 +         *  @site          The type of the qualifier
   1.246 +         */
   1.247 +        private
   1.248 +        boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) {
   1.249 +            while (c != null &&
   1.250 +                   !(c.isSubClass(sym.owner, types) &&
   1.251 +                     (c.flags() & INTERFACE) == 0 &&
   1.252 +                     // In JLS 2e 6.6.2.1, the subclass restriction applies
   1.253 +                     // only to instance fields and methods -- types are excluded
   1.254 +                     // regardless of whether they are declared 'static' or not.
   1.255 +                     ((sym.flags() & STATIC) != 0 || sym.kind == TYP || site.tsym.isSubClass(c, types))))
   1.256 +                c = c.owner.enclClass();
   1.257 +            return c != null;
   1.258 +        }
   1.259 +
   1.260 +    /** Try to instantiate the type of a method so that it fits
   1.261 +     *  given type arguments and argument types. If succesful, return
   1.262 +     *  the method's instantiated type, else return null.
   1.263 +     *  The instantiation will take into account an additional leading
   1.264 +     *  formal parameter if the method is an instance method seen as a member
   1.265 +     *  of un underdetermined site In this case, we treat site as an additional
   1.266 +     *  parameter and the parameters of the class containing the method as
   1.267 +     *  additional type variables that get instantiated.
   1.268 +     *
   1.269 +     *  @param env         The current environment
   1.270 +     *  @param site        The type of which the method is a member.
   1.271 +     *  @param m           The method symbol.
   1.272 +     *  @param argtypes    The invocation's given value arguments.
   1.273 +     *  @param typeargtypes    The invocation's given type arguments.
   1.274 +     *  @param allowBoxing Allow boxing conversions of arguments.
   1.275 +     *  @param useVarargs Box trailing arguments into an array for varargs.
   1.276 +     */
   1.277 +    Type rawInstantiate(Env<AttrContext> env,
   1.278 +                        Type site,
   1.279 +                        Symbol m,
   1.280 +                        List<Type> argtypes,
   1.281 +                        List<Type> typeargtypes,
   1.282 +                        boolean allowBoxing,
   1.283 +                        boolean useVarargs,
   1.284 +                        Warner warn)
   1.285 +        throws Infer.NoInstanceException {
   1.286 +        if (useVarargs && (m.flags() & VARARGS) == 0) return null;
   1.287 +        Type mt = types.memberType(site, m);
   1.288 +
   1.289 +        // tvars is the list of formal type variables for which type arguments
   1.290 +        // need to inferred.
   1.291 +        List<Type> tvars = env.info.tvars;
   1.292 +        if (typeargtypes == null) typeargtypes = List.nil();
   1.293 +        if (mt.tag != FORALL && typeargtypes.nonEmpty()) {
   1.294 +            // This is not a polymorphic method, but typeargs are supplied
   1.295 +            // which is fine, see JLS3 15.12.2.1
   1.296 +        } else if (mt.tag == FORALL && typeargtypes.nonEmpty()) {
   1.297 +            ForAll pmt = (ForAll) mt;
   1.298 +            if (typeargtypes.length() != pmt.tvars.length())
   1.299 +                return null;
   1.300 +            // Check type arguments are within bounds
   1.301 +            List<Type> formals = pmt.tvars;
   1.302 +            List<Type> actuals = typeargtypes;
   1.303 +            while (formals.nonEmpty() && actuals.nonEmpty()) {
   1.304 +                List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head),
   1.305 +                                                pmt.tvars, typeargtypes);
   1.306 +                for (; bounds.nonEmpty(); bounds = bounds.tail)
   1.307 +                    if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn))
   1.308 +                        return null;
   1.309 +                formals = formals.tail;
   1.310 +                actuals = actuals.tail;
   1.311 +            }
   1.312 +            mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes);
   1.313 +        } else if (mt.tag == FORALL) {
   1.314 +            ForAll pmt = (ForAll) mt;
   1.315 +            List<Type> tvars1 = types.newInstances(pmt.tvars);
   1.316 +            tvars = tvars.appendList(tvars1);
   1.317 +            mt = types.subst(pmt.qtype, pmt.tvars, tvars1);
   1.318 +        }
   1.319 +
   1.320 +        // find out whether we need to go the slow route via infer
   1.321 +        boolean instNeeded = tvars.tail != null/*inlined: tvars.nonEmpty()*/;
   1.322 +        for (List<Type> l = argtypes;
   1.323 +             l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
   1.324 +             l = l.tail) {
   1.325 +            if (l.head.tag == FORALL) instNeeded = true;
   1.326 +        }
   1.327 +
   1.328 +        if (instNeeded)
   1.329 +            return
   1.330 +            infer.instantiateMethod(tvars,
   1.331 +                                    (MethodType)mt,
   1.332 +                                    argtypes,
   1.333 +                                    allowBoxing,
   1.334 +                                    useVarargs,
   1.335 +                                    warn);
   1.336 +        return
   1.337 +            argumentsAcceptable(argtypes, mt.getParameterTypes(),
   1.338 +                                allowBoxing, useVarargs, warn)
   1.339 +            ? mt
   1.340 +            : null;
   1.341 +    }
   1.342 +
   1.343 +    /** Same but returns null instead throwing a NoInstanceException
   1.344 +     */
   1.345 +    Type instantiate(Env<AttrContext> env,
   1.346 +                     Type site,
   1.347 +                     Symbol m,
   1.348 +                     List<Type> argtypes,
   1.349 +                     List<Type> typeargtypes,
   1.350 +                     boolean allowBoxing,
   1.351 +                     boolean useVarargs,
   1.352 +                     Warner warn) {
   1.353 +        try {
   1.354 +            return rawInstantiate(env, site, m, argtypes, typeargtypes,
   1.355 +                                  allowBoxing, useVarargs, warn);
   1.356 +        } catch (Infer.NoInstanceException ex) {
   1.357 +            return null;
   1.358 +        }
   1.359 +    }
   1.360 +
   1.361 +    /** Check if a parameter list accepts a list of args.
   1.362 +     */
   1.363 +    boolean argumentsAcceptable(List<Type> argtypes,
   1.364 +                                List<Type> formals,
   1.365 +                                boolean allowBoxing,
   1.366 +                                boolean useVarargs,
   1.367 +                                Warner warn) {
   1.368 +        Type varargsFormal = useVarargs ? formals.last() : null;
   1.369 +        while (argtypes.nonEmpty() && formals.head != varargsFormal) {
   1.370 +            boolean works = allowBoxing
   1.371 +                ? types.isConvertible(argtypes.head, formals.head, warn)
   1.372 +                : types.isSubtypeUnchecked(argtypes.head, formals.head, warn);
   1.373 +            if (!works) return false;
   1.374 +            argtypes = argtypes.tail;
   1.375 +            formals = formals.tail;
   1.376 +        }
   1.377 +        if (formals.head != varargsFormal) return false; // not enough args
   1.378 +        if (!useVarargs)
   1.379 +            return argtypes.isEmpty();
   1.380 +        Type elt = types.elemtype(varargsFormal);
   1.381 +        while (argtypes.nonEmpty()) {
   1.382 +            if (!types.isConvertible(argtypes.head, elt, warn))
   1.383 +                return false;
   1.384 +            argtypes = argtypes.tail;
   1.385 +        }
   1.386 +        return true;
   1.387 +    }
   1.388 +
   1.389 +/* ***************************************************************************
   1.390 + *  Symbol lookup
   1.391 + *  the following naming conventions for arguments are used
   1.392 + *
   1.393 + *       env      is the environment where the symbol was mentioned
   1.394 + *       site     is the type of which the symbol is a member
   1.395 + *       name     is the symbol's name
   1.396 + *                if no arguments are given
   1.397 + *       argtypes are the value arguments, if we search for a method
   1.398 + *
   1.399 + *  If no symbol was found, a ResolveError detailing the problem is returned.
   1.400 + ****************************************************************************/
   1.401 +
   1.402 +    /** Find field. Synthetic fields are always skipped.
   1.403 +     *  @param env     The current environment.
   1.404 +     *  @param site    The original type from where the selection takes place.
   1.405 +     *  @param name    The name of the field.
   1.406 +     *  @param c       The class to search for the field. This is always
   1.407 +     *                 a superclass or implemented interface of site's class.
   1.408 +     */
   1.409 +    Symbol findField(Env<AttrContext> env,
   1.410 +                     Type site,
   1.411 +                     Name name,
   1.412 +                     TypeSymbol c) {
   1.413 +        Symbol bestSoFar = varNotFound;
   1.414 +        Symbol sym;
   1.415 +        Scope.Entry e = c.members().lookup(name);
   1.416 +        while (e.scope != null) {
   1.417 +            if (e.sym.kind == VAR && (e.sym.flags_field & SYNTHETIC) == 0) {
   1.418 +                return isAccessible(env, site, e.sym)
   1.419 +                    ? e.sym : new AccessError(env, site, e.sym);
   1.420 +            }
   1.421 +            e = e.next();
   1.422 +        }
   1.423 +        Type st = types.supertype(c.type);
   1.424 +        if (st != null && st.tag == CLASS) {
   1.425 +            sym = findField(env, site, name, st.tsym);
   1.426 +            if (sym.kind < bestSoFar.kind) bestSoFar = sym;
   1.427 +        }
   1.428 +        for (List<Type> l = types.interfaces(c.type);
   1.429 +             bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
   1.430 +             l = l.tail) {
   1.431 +            sym = findField(env, site, name, l.head.tsym);
   1.432 +            if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&
   1.433 +                sym.owner != bestSoFar.owner)
   1.434 +                bestSoFar = new AmbiguityError(bestSoFar, sym);
   1.435 +            else if (sym.kind < bestSoFar.kind)
   1.436 +                bestSoFar = sym;
   1.437 +        }
   1.438 +        return bestSoFar;
   1.439 +    }
   1.440 +
   1.441 +    /** Resolve a field identifier, throw a fatal error if not found.
   1.442 +     *  @param pos       The position to use for error reporting.
   1.443 +     *  @param env       The environment current at the method invocation.
   1.444 +     *  @param site      The type of the qualifying expression, in which
   1.445 +     *                   identifier is searched.
   1.446 +     *  @param name      The identifier's name.
   1.447 +     */
   1.448 +    public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env,
   1.449 +                                          Type site, Name name) {
   1.450 +        Symbol sym = findField(env, site, name, site.tsym);
   1.451 +        if (sym.kind == VAR) return (VarSymbol)sym;
   1.452 +        else throw new FatalError(
   1.453 +                 JCDiagnostic.fragment("fatal.err.cant.locate.field",
   1.454 +                                name));
   1.455 +    }
   1.456 +
   1.457 +    /** Find unqualified variable or field with given name.
   1.458 +     *  Synthetic fields always skipped.
   1.459 +     *  @param env     The current environment.
   1.460 +     *  @param name    The name of the variable or field.
   1.461 +     */
   1.462 +    Symbol findVar(Env<AttrContext> env, Name name) {
   1.463 +        Symbol bestSoFar = varNotFound;
   1.464 +        Symbol sym;
   1.465 +        Env<AttrContext> env1 = env;
   1.466 +        boolean staticOnly = false;
   1.467 +        while (env1.outer != null) {
   1.468 +            if (isStatic(env1)) staticOnly = true;
   1.469 +            Scope.Entry e = env1.info.scope.lookup(name);
   1.470 +            while (e.scope != null &&
   1.471 +                   (e.sym.kind != VAR ||
   1.472 +                    (e.sym.flags_field & SYNTHETIC) != 0))
   1.473 +                e = e.next();
   1.474 +            sym = (e.scope != null)
   1.475 +                ? e.sym
   1.476 +                : findField(
   1.477 +                    env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
   1.478 +            if (sym.exists()) {
   1.479 +                if (staticOnly &&
   1.480 +                    sym.kind == VAR &&
   1.481 +                    sym.owner.kind == TYP &&
   1.482 +                    (sym.flags() & STATIC) == 0)
   1.483 +                    return new StaticError(sym);
   1.484 +                else
   1.485 +                    return sym;
   1.486 +            } else if (sym.kind < bestSoFar.kind) {
   1.487 +                bestSoFar = sym;
   1.488 +            }
   1.489 +
   1.490 +            if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
   1.491 +            env1 = env1.outer;
   1.492 +        }
   1.493 +
   1.494 +        sym = findField(env, syms.predefClass.type, name, syms.predefClass);
   1.495 +        if (sym.exists())
   1.496 +            return sym;
   1.497 +        if (bestSoFar.exists())
   1.498 +            return bestSoFar;
   1.499 +
   1.500 +        Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
   1.501 +        for (; e.scope != null; e = e.next()) {
   1.502 +            sym = e.sym;
   1.503 +            Type origin = e.getOrigin().owner.type;
   1.504 +            if (sym.kind == VAR) {
   1.505 +                if (e.sym.owner.type != origin)
   1.506 +                    sym = sym.clone(e.getOrigin().owner);
   1.507 +                return isAccessible(env, origin, sym)
   1.508 +                    ? sym : new AccessError(env, origin, sym);
   1.509 +            }
   1.510 +        }
   1.511 +
   1.512 +        Symbol origin = null;
   1.513 +        e = env.toplevel.starImportScope.lookup(name);
   1.514 +        for (; e.scope != null; e = e.next()) {
   1.515 +            sym = e.sym;
   1.516 +            if (sym.kind != VAR)
   1.517 +                continue;
   1.518 +            // invariant: sym.kind == VAR
   1.519 +            if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner)
   1.520 +                return new AmbiguityError(bestSoFar, sym);
   1.521 +            else if (bestSoFar.kind >= VAR) {
   1.522 +                origin = e.getOrigin().owner;
   1.523 +                bestSoFar = isAccessible(env, origin.type, sym)
   1.524 +                    ? sym : new AccessError(env, origin.type, sym);
   1.525 +            }
   1.526 +        }
   1.527 +        if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type)
   1.528 +            return bestSoFar.clone(origin);
   1.529 +        else
   1.530 +            return bestSoFar;
   1.531 +    }
   1.532 +
   1.533 +    Warner noteWarner = new Warner();
   1.534 +
   1.535 +    /** Select the best method for a call site among two choices.
   1.536 +     *  @param env              The current environment.
   1.537 +     *  @param site             The original type from where the
   1.538 +     *                          selection takes place.
   1.539 +     *  @param argtypes         The invocation's value arguments,
   1.540 +     *  @param typeargtypes     The invocation's type arguments,
   1.541 +     *  @param sym              Proposed new best match.
   1.542 +     *  @param bestSoFar        Previously found best match.
   1.543 +     *  @param allowBoxing Allow boxing conversions of arguments.
   1.544 +     *  @param useVarargs Box trailing arguments into an array for varargs.
   1.545 +     */
   1.546 +    Symbol selectBest(Env<AttrContext> env,
   1.547 +                      Type site,
   1.548 +                      List<Type> argtypes,
   1.549 +                      List<Type> typeargtypes,
   1.550 +                      Symbol sym,
   1.551 +                      Symbol bestSoFar,
   1.552 +                      boolean allowBoxing,
   1.553 +                      boolean useVarargs,
   1.554 +                      boolean operator) {
   1.555 +        if (sym.kind == ERR) return bestSoFar;
   1.556 +        if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
   1.557 +        assert sym.kind < AMBIGUOUS;
   1.558 +        try {
   1.559 +            if (rawInstantiate(env, site, sym, argtypes, typeargtypes,
   1.560 +                               allowBoxing, useVarargs, Warner.noWarnings) == null) {
   1.561 +                // inapplicable
   1.562 +                switch (bestSoFar.kind) {
   1.563 +                case ABSENT_MTH: return wrongMethod.setWrongSym(sym);
   1.564 +                case WRONG_MTH: return wrongMethods;
   1.565 +                default: return bestSoFar;
   1.566 +                }
   1.567 +            }
   1.568 +        } catch (Infer.NoInstanceException ex) {
   1.569 +            switch (bestSoFar.kind) {
   1.570 +            case ABSENT_MTH:
   1.571 +                return wrongMethod.setWrongSym(sym, ex.getDiagnostic());
   1.572 +            case WRONG_MTH:
   1.573 +                return wrongMethods;
   1.574 +            default:
   1.575 +                return bestSoFar;
   1.576 +            }
   1.577 +        }
   1.578 +        if (!isAccessible(env, site, sym)) {
   1.579 +            return (bestSoFar.kind == ABSENT_MTH)
   1.580 +                ? new AccessError(env, site, sym)
   1.581 +                : bestSoFar;
   1.582 +        }
   1.583 +        return (bestSoFar.kind > AMBIGUOUS)
   1.584 +            ? sym
   1.585 +            : mostSpecific(sym, bestSoFar, env, site,
   1.586 +                           allowBoxing && operator, useVarargs);
   1.587 +    }
   1.588 +
   1.589 +    /* Return the most specific of the two methods for a call,
   1.590 +     *  given that both are accessible and applicable.
   1.591 +     *  @param m1               A new candidate for most specific.
   1.592 +     *  @param m2               The previous most specific candidate.
   1.593 +     *  @param env              The current environment.
   1.594 +     *  @param site             The original type from where the selection
   1.595 +     *                          takes place.
   1.596 +     *  @param allowBoxing Allow boxing conversions of arguments.
   1.597 +     *  @param useVarargs Box trailing arguments into an array for varargs.
   1.598 +     */
   1.599 +    Symbol mostSpecific(Symbol m1,
   1.600 +                        Symbol m2,
   1.601 +                        Env<AttrContext> env,
   1.602 +                        Type site,
   1.603 +                        boolean allowBoxing,
   1.604 +                        boolean useVarargs) {
   1.605 +        switch (m2.kind) {
   1.606 +        case MTH:
   1.607 +            if (m1 == m2) return m1;
   1.608 +            Type mt1 = types.memberType(site, m1);
   1.609 +            noteWarner.unchecked = false;
   1.610 +            boolean m1SignatureMoreSpecific =
   1.611 +                (instantiate(env, site, m2, types.lowerBoundArgtypes(mt1), null,
   1.612 +                             allowBoxing, false, noteWarner) != null ||
   1.613 +                 useVarargs && instantiate(env, site, m2, types.lowerBoundArgtypes(mt1), null,
   1.614 +                                           allowBoxing, true, noteWarner) != null) &&
   1.615 +                !noteWarner.unchecked;
   1.616 +            Type mt2 = types.memberType(site, m2);
   1.617 +            noteWarner.unchecked = false;
   1.618 +            boolean m2SignatureMoreSpecific =
   1.619 +                (instantiate(env, site, m1, types.lowerBoundArgtypes(mt2), null,
   1.620 +                             allowBoxing, false, noteWarner) != null ||
   1.621 +                 useVarargs && instantiate(env, site, m1, types.lowerBoundArgtypes(mt2), null,
   1.622 +                                           allowBoxing, true, noteWarner) != null) &&
   1.623 +                !noteWarner.unchecked;
   1.624 +            if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) {
   1.625 +                if (!types.overrideEquivalent(mt1, mt2))
   1.626 +                    return new AmbiguityError(m1, m2);
   1.627 +                // same signature; select (a) the non-bridge method, or
   1.628 +                // (b) the one that overrides the other, or (c) the concrete
   1.629 +                // one, or (d) merge both abstract signatures
   1.630 +                if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE)) {
   1.631 +                    return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
   1.632 +                }
   1.633 +                // if one overrides or hides the other, use it
   1.634 +                TypeSymbol m1Owner = (TypeSymbol)m1.owner;
   1.635 +                TypeSymbol m2Owner = (TypeSymbol)m2.owner;
   1.636 +                if (types.asSuper(m1Owner.type, m2Owner) != null &&
   1.637 +                    ((m1.owner.flags_field & INTERFACE) == 0 ||
   1.638 +                     (m2.owner.flags_field & INTERFACE) != 0) &&
   1.639 +                    m1.overrides(m2, m1Owner, types, false))
   1.640 +                    return m1;
   1.641 +                if (types.asSuper(m2Owner.type, m1Owner) != null &&
   1.642 +                    ((m2.owner.flags_field & INTERFACE) == 0 ||
   1.643 +                     (m1.owner.flags_field & INTERFACE) != 0) &&
   1.644 +                    m2.overrides(m1, m2Owner, types, false))
   1.645 +                    return m2;
   1.646 +                boolean m1Abstract = (m1.flags() & ABSTRACT) != 0;
   1.647 +                boolean m2Abstract = (m2.flags() & ABSTRACT) != 0;
   1.648 +                if (m1Abstract && !m2Abstract) return m2;
   1.649 +                if (m2Abstract && !m1Abstract) return m1;
   1.650 +                // both abstract or both concrete
   1.651 +                if (!m1Abstract && !m2Abstract)
   1.652 +                    return new AmbiguityError(m1, m2);
   1.653 +                // check for same erasure
   1.654 +                if (!types.isSameType(m1.erasure(types), m2.erasure(types)))
   1.655 +                    return new AmbiguityError(m1, m2);
   1.656 +                // both abstract, neither overridden; merge throws clause and result type
   1.657 +                Symbol result;
   1.658 +                Type result2 = mt2.getReturnType();;
   1.659 +                if (mt2.tag == FORALL)
   1.660 +                    result2 = types.subst(result2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars);
   1.661 +                if (types.isSubtype(mt1.getReturnType(), result2)) {
   1.662 +                    result = m1;
   1.663 +                } else if (types.isSubtype(result2, mt1.getReturnType())) {
   1.664 +                    result = m2;
   1.665 +                } else {
   1.666 +                    // Theoretically, this can't happen, but it is possible
   1.667 +                    // due to error recovery or mixing incompatible class files
   1.668 +                    return new AmbiguityError(m1, m2);
   1.669 +                }
   1.670 +                result = result.clone(result.owner);
   1.671 +                result.type = (Type)result.type.clone();
   1.672 +                result.type.setThrown(chk.intersect(mt1.getThrownTypes(),
   1.673 +                                                    mt2.getThrownTypes()));
   1.674 +                return result;
   1.675 +            }
   1.676 +            if (m1SignatureMoreSpecific) return m1;
   1.677 +            if (m2SignatureMoreSpecific) return m2;
   1.678 +            return new AmbiguityError(m1, m2);
   1.679 +        case AMBIGUOUS:
   1.680 +            AmbiguityError e = (AmbiguityError)m2;
   1.681 +            Symbol err1 = mostSpecific(m1, e.sym1, env, site, allowBoxing, useVarargs);
   1.682 +            Symbol err2 = mostSpecific(m1, e.sym2, env, site, allowBoxing, useVarargs);
   1.683 +            if (err1 == err2) return err1;
   1.684 +            if (err1 == e.sym1 && err2 == e.sym2) return m2;
   1.685 +            if (err1 instanceof AmbiguityError &&
   1.686 +                err2 instanceof AmbiguityError &&
   1.687 +                ((AmbiguityError)err1).sym1 == ((AmbiguityError)err2).sym1)
   1.688 +                return new AmbiguityError(m1, m2);
   1.689 +            else
   1.690 +                return new AmbiguityError(err1, err2);
   1.691 +        default:
   1.692 +            throw new AssertionError();
   1.693 +        }
   1.694 +    }
   1.695 +
   1.696 +    /** Find best qualified method matching given name, type and value
   1.697 +     *  arguments.
   1.698 +     *  @param env       The current environment.
   1.699 +     *  @param site      The original type from where the selection
   1.700 +     *                   takes place.
   1.701 +     *  @param name      The method's name.
   1.702 +     *  @param argtypes  The method's value arguments.
   1.703 +     *  @param typeargtypes The method's type arguments
   1.704 +     *  @param allowBoxing Allow boxing conversions of arguments.
   1.705 +     *  @param useVarargs Box trailing arguments into an array for varargs.
   1.706 +     */
   1.707 +    Symbol findMethod(Env<AttrContext> env,
   1.708 +                      Type site,
   1.709 +                      Name name,
   1.710 +                      List<Type> argtypes,
   1.711 +                      List<Type> typeargtypes,
   1.712 +                      boolean allowBoxing,
   1.713 +                      boolean useVarargs,
   1.714 +                      boolean operator) {
   1.715 +        return findMethod(env,
   1.716 +                          site,
   1.717 +                          name,
   1.718 +                          argtypes,
   1.719 +                          typeargtypes,
   1.720 +                          site.tsym.type,
   1.721 +                          true,
   1.722 +                          methodNotFound,
   1.723 +                          allowBoxing,
   1.724 +                          useVarargs,
   1.725 +                          operator);
   1.726 +    }
   1.727 +    // where
   1.728 +    private Symbol findMethod(Env<AttrContext> env,
   1.729 +                              Type site,
   1.730 +                              Name name,
   1.731 +                              List<Type> argtypes,
   1.732 +                              List<Type> typeargtypes,
   1.733 +                              Type intype,
   1.734 +                              boolean abstractok,
   1.735 +                              Symbol bestSoFar,
   1.736 +                              boolean allowBoxing,
   1.737 +                              boolean useVarargs,
   1.738 +                              boolean operator) {
   1.739 +        for (Type ct = intype; ct.tag == CLASS; ct = types.supertype(ct)) {
   1.740 +            ClassSymbol c = (ClassSymbol)ct.tsym;
   1.741 +            if ((c.flags() & (ABSTRACT | INTERFACE)) == 0)
   1.742 +                abstractok = false;
   1.743 +            for (Scope.Entry e = c.members().lookup(name);
   1.744 +                 e.scope != null;
   1.745 +                 e = e.next()) {
   1.746 +                //- System.out.println(" e " + e.sym);
   1.747 +                if (e.sym.kind == MTH &&
   1.748 +                    (e.sym.flags_field & SYNTHETIC) == 0) {
   1.749 +                    bestSoFar = selectBest(env, site, argtypes, typeargtypes,
   1.750 +                                           e.sym, bestSoFar,
   1.751 +                                           allowBoxing,
   1.752 +                                           useVarargs,
   1.753 +                                           operator);
   1.754 +                }
   1.755 +            }
   1.756 +            //- System.out.println(" - " + bestSoFar);
   1.757 +            if (abstractok) {
   1.758 +                Symbol concrete = methodNotFound;
   1.759 +                if ((bestSoFar.flags() & ABSTRACT) == 0)
   1.760 +                    concrete = bestSoFar;
   1.761 +                for (List<Type> l = types.interfaces(c.type);
   1.762 +                     l.nonEmpty();
   1.763 +                     l = l.tail) {
   1.764 +                    bestSoFar = findMethod(env, site, name, argtypes,
   1.765 +                                           typeargtypes,
   1.766 +                                           l.head, abstractok, bestSoFar,
   1.767 +                                           allowBoxing, useVarargs, operator);
   1.768 +                }
   1.769 +                if (concrete != bestSoFar &&
   1.770 +                    concrete.kind < ERR  && bestSoFar.kind < ERR &&
   1.771 +                    types.isSubSignature(concrete.type, bestSoFar.type))
   1.772 +                    bestSoFar = concrete;
   1.773 +            }
   1.774 +        }
   1.775 +        return bestSoFar;
   1.776 +    }
   1.777 +
   1.778 +    /** Find unqualified method matching given name, type and value arguments.
   1.779 +     *  @param env       The current environment.
   1.780 +     *  @param name      The method's name.
   1.781 +     *  @param argtypes  The method's value arguments.
   1.782 +     *  @param typeargtypes  The method's type arguments.
   1.783 +     *  @param allowBoxing Allow boxing conversions of arguments.
   1.784 +     *  @param useVarargs Box trailing arguments into an array for varargs.
   1.785 +     */
   1.786 +    Symbol findFun(Env<AttrContext> env, Name name,
   1.787 +                   List<Type> argtypes, List<Type> typeargtypes,
   1.788 +                   boolean allowBoxing, boolean useVarargs) {
   1.789 +        Symbol bestSoFar = methodNotFound;
   1.790 +        Symbol sym;
   1.791 +        Env<AttrContext> env1 = env;
   1.792 +        boolean staticOnly = false;
   1.793 +        while (env1.outer != null) {
   1.794 +            if (isStatic(env1)) staticOnly = true;
   1.795 +            sym = findMethod(
   1.796 +                env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
   1.797 +                allowBoxing, useVarargs, false);
   1.798 +            if (sym.exists()) {
   1.799 +                if (staticOnly &&
   1.800 +                    sym.kind == MTH &&
   1.801 +                    sym.owner.kind == TYP &&
   1.802 +                    (sym.flags() & STATIC) == 0) return new StaticError(sym);
   1.803 +                else return sym;
   1.804 +            } else if (sym.kind < bestSoFar.kind) {
   1.805 +                bestSoFar = sym;
   1.806 +            }
   1.807 +            if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
   1.808 +            env1 = env1.outer;
   1.809 +        }
   1.810 +
   1.811 +        sym = findMethod(env, syms.predefClass.type, name, argtypes,
   1.812 +                         typeargtypes, allowBoxing, useVarargs, false);
   1.813 +        if (sym.exists())
   1.814 +            return sym;
   1.815 +
   1.816 +        Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
   1.817 +        for (; e.scope != null; e = e.next()) {
   1.818 +            sym = e.sym;
   1.819 +            Type origin = e.getOrigin().owner.type;
   1.820 +            if (sym.kind == MTH) {
   1.821 +                if (e.sym.owner.type != origin)
   1.822 +                    sym = sym.clone(e.getOrigin().owner);
   1.823 +                if (!isAccessible(env, origin, sym))
   1.824 +                    sym = new AccessError(env, origin, sym);
   1.825 +                bestSoFar = selectBest(env, origin,
   1.826 +                                       argtypes, typeargtypes,
   1.827 +                                       sym, bestSoFar,
   1.828 +                                       allowBoxing, useVarargs, false);
   1.829 +            }
   1.830 +        }
   1.831 +        if (bestSoFar.exists())
   1.832 +            return bestSoFar;
   1.833 +
   1.834 +        e = env.toplevel.starImportScope.lookup(name);
   1.835 +        for (; e.scope != null; e = e.next()) {
   1.836 +            sym = e.sym;
   1.837 +            Type origin = e.getOrigin().owner.type;
   1.838 +            if (sym.kind == MTH) {
   1.839 +                if (e.sym.owner.type != origin)
   1.840 +                    sym = sym.clone(e.getOrigin().owner);
   1.841 +                if (!isAccessible(env, origin, sym))
   1.842 +                    sym = new AccessError(env, origin, sym);
   1.843 +                bestSoFar = selectBest(env, origin,
   1.844 +                                       argtypes, typeargtypes,
   1.845 +                                       sym, bestSoFar,
   1.846 +                                       allowBoxing, useVarargs, false);
   1.847 +            }
   1.848 +        }
   1.849 +        return bestSoFar;
   1.850 +    }
   1.851 +
   1.852 +    /** Load toplevel or member class with given fully qualified name and
   1.853 +     *  verify that it is accessible.
   1.854 +     *  @param env       The current environment.
   1.855 +     *  @param name      The fully qualified name of the class to be loaded.
   1.856 +     */
   1.857 +    Symbol loadClass(Env<AttrContext> env, Name name) {
   1.858 +        try {
   1.859 +            ClassSymbol c = reader.loadClass(name);
   1.860 +            return isAccessible(env, c) ? c : new AccessError(c);
   1.861 +        } catch (ClassReader.BadClassFile err) {
   1.862 +            throw err;
   1.863 +        } catch (CompletionFailure ex) {
   1.864 +            return typeNotFound;
   1.865 +        }
   1.866 +    }
   1.867 +
   1.868 +    /** Find qualified member type.
   1.869 +     *  @param env       The current environment.
   1.870 +     *  @param site      The original type from where the selection takes
   1.871 +     *                   place.
   1.872 +     *  @param name      The type's name.
   1.873 +     *  @param c         The class to search for the member type. This is
   1.874 +     *                   always a superclass or implemented interface of
   1.875 +     *                   site's class.
   1.876 +     */
   1.877 +    Symbol findMemberType(Env<AttrContext> env,
   1.878 +                          Type site,
   1.879 +                          Name name,
   1.880 +                          TypeSymbol c) {
   1.881 +        Symbol bestSoFar = typeNotFound;
   1.882 +        Symbol sym;
   1.883 +        Scope.Entry e = c.members().lookup(name);
   1.884 +        while (e.scope != null) {
   1.885 +            if (e.sym.kind == TYP) {
   1.886 +                return isAccessible(env, site, e.sym)
   1.887 +                    ? e.sym
   1.888 +                    : new AccessError(env, site, e.sym);
   1.889 +            }
   1.890 +            e = e.next();
   1.891 +        }
   1.892 +        Type st = types.supertype(c.type);
   1.893 +        if (st != null && st.tag == CLASS) {
   1.894 +            sym = findMemberType(env, site, name, st.tsym);
   1.895 +            if (sym.kind < bestSoFar.kind) bestSoFar = sym;
   1.896 +        }
   1.897 +        for (List<Type> l = types.interfaces(c.type);
   1.898 +             bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
   1.899 +             l = l.tail) {
   1.900 +            sym = findMemberType(env, site, name, l.head.tsym);
   1.901 +            if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&
   1.902 +                sym.owner != bestSoFar.owner)
   1.903 +                bestSoFar = new AmbiguityError(bestSoFar, sym);
   1.904 +            else if (sym.kind < bestSoFar.kind)
   1.905 +                bestSoFar = sym;
   1.906 +        }
   1.907 +        return bestSoFar;
   1.908 +    }
   1.909 +
   1.910 +    /** Find a global type in given scope and load corresponding class.
   1.911 +     *  @param env       The current environment.
   1.912 +     *  @param scope     The scope in which to look for the type.
   1.913 +     *  @param name      The type's name.
   1.914 +     */
   1.915 +    Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {
   1.916 +        Symbol bestSoFar = typeNotFound;
   1.917 +        for (Scope.Entry e = scope.lookup(name); e.scope != null; e = e.next()) {
   1.918 +            Symbol sym = loadClass(env, e.sym.flatName());
   1.919 +            if (bestSoFar.kind == TYP && sym.kind == TYP &&
   1.920 +                bestSoFar != sym)
   1.921 +                return new AmbiguityError(bestSoFar, sym);
   1.922 +            else if (sym.kind < bestSoFar.kind)
   1.923 +                bestSoFar = sym;
   1.924 +        }
   1.925 +        return bestSoFar;
   1.926 +    }
   1.927 +
   1.928 +    /** Find an unqualified type symbol.
   1.929 +     *  @param env       The current environment.
   1.930 +     *  @param name      The type's name.
   1.931 +     */
   1.932 +    Symbol findType(Env<AttrContext> env, Name name) {
   1.933 +        Symbol bestSoFar = typeNotFound;
   1.934 +        Symbol sym;
   1.935 +        boolean staticOnly = false;
   1.936 +        for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {
   1.937 +            if (isStatic(env1)) staticOnly = true;
   1.938 +            for (Scope.Entry e = env1.info.scope.lookup(name);
   1.939 +                 e.scope != null;
   1.940 +                 e = e.next()) {
   1.941 +                if (e.sym.kind == TYP) {
   1.942 +                    if (staticOnly &&
   1.943 +                        e.sym.type.tag == TYPEVAR &&
   1.944 +                        e.sym.owner.kind == TYP) return new StaticError(e.sym);
   1.945 +                    return e.sym;
   1.946 +                }
   1.947 +            }
   1.948 +
   1.949 +            sym = findMemberType(env1, env1.enclClass.sym.type, name,
   1.950 +                                 env1.enclClass.sym);
   1.951 +            if (staticOnly && sym.kind == TYP &&
   1.952 +                sym.type.tag == CLASS &&
   1.953 +                sym.type.getEnclosingType().tag == CLASS &&
   1.954 +                env1.enclClass.sym.type.isParameterized() &&
   1.955 +                sym.type.getEnclosingType().isParameterized())
   1.956 +                return new StaticError(sym);
   1.957 +            else if (sym.exists()) return sym;
   1.958 +            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
   1.959 +
   1.960 +            JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass;
   1.961 +            if ((encl.sym.flags() & STATIC) != 0)
   1.962 +                staticOnly = true;
   1.963 +        }
   1.964 +
   1.965 +        if (env.tree.getTag() != JCTree.IMPORT) {
   1.966 +            sym = findGlobalType(env, env.toplevel.namedImportScope, name);
   1.967 +            if (sym.exists()) return sym;
   1.968 +            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
   1.969 +
   1.970 +            sym = findGlobalType(env, env.toplevel.packge.members(), name);
   1.971 +            if (sym.exists()) return sym;
   1.972 +            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
   1.973 +
   1.974 +            sym = findGlobalType(env, env.toplevel.starImportScope, name);
   1.975 +            if (sym.exists()) return sym;
   1.976 +            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
   1.977 +        }
   1.978 +
   1.979 +        return bestSoFar;
   1.980 +    }
   1.981 +
   1.982 +    /** Find an unqualified identifier which matches a specified kind set.
   1.983 +     *  @param env       The current environment.
   1.984 +     *  @param name      The indentifier's name.
   1.985 +     *  @param kind      Indicates the possible symbol kinds
   1.986 +     *                   (a subset of VAL, TYP, PCK).
   1.987 +     */
   1.988 +    Symbol findIdent(Env<AttrContext> env, Name name, int kind) {
   1.989 +        Symbol bestSoFar = typeNotFound;
   1.990 +        Symbol sym;
   1.991 +
   1.992 +        if ((kind & VAR) != 0) {
   1.993 +            sym = findVar(env, name);
   1.994 +            if (sym.exists()) return sym;
   1.995 +            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
   1.996 +        }
   1.997 +
   1.998 +        if ((kind & TYP) != 0) {
   1.999 +            sym = findType(env, name);
  1.1000 +            if (sym.exists()) return sym;
  1.1001 +            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
  1.1002 +        }
  1.1003 +
  1.1004 +        if ((kind & PCK) != 0) return reader.enterPackage(name);
  1.1005 +        else return bestSoFar;
  1.1006 +    }
  1.1007 +
  1.1008 +    /** Find an identifier in a package which matches a specified kind set.
  1.1009 +     *  @param env       The current environment.
  1.1010 +     *  @param name      The identifier's name.
  1.1011 +     *  @param kind      Indicates the possible symbol kinds
  1.1012 +     *                   (a nonempty subset of TYP, PCK).
  1.1013 +     */
  1.1014 +    Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck,
  1.1015 +                              Name name, int kind) {
  1.1016 +        Name fullname = TypeSymbol.formFullName(name, pck);
  1.1017 +        Symbol bestSoFar = typeNotFound;
  1.1018 +        PackageSymbol pack = null;
  1.1019 +        if ((kind & PCK) != 0) {
  1.1020 +            pack = reader.enterPackage(fullname);
  1.1021 +            if (pack.exists()) return pack;
  1.1022 +        }
  1.1023 +        if ((kind & TYP) != 0) {
  1.1024 +            Symbol sym = loadClass(env, fullname);
  1.1025 +            if (sym.exists()) {
  1.1026 +                // don't allow programs to use flatnames
  1.1027 +                if (name == sym.name) return sym;
  1.1028 +            }
  1.1029 +            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
  1.1030 +        }
  1.1031 +        return (pack != null) ? pack : bestSoFar;
  1.1032 +    }
  1.1033 +
  1.1034 +    /** Find an identifier among the members of a given type `site'.
  1.1035 +     *  @param env       The current environment.
  1.1036 +     *  @param site      The type containing the symbol to be found.
  1.1037 +     *  @param name      The identifier's name.
  1.1038 +     *  @param kind      Indicates the possible symbol kinds
  1.1039 +     *                   (a subset of VAL, TYP).
  1.1040 +     */
  1.1041 +    Symbol findIdentInType(Env<AttrContext> env, Type site,
  1.1042 +                           Name name, int kind) {
  1.1043 +        Symbol bestSoFar = typeNotFound;
  1.1044 +        Symbol sym;
  1.1045 +        if ((kind & VAR) != 0) {
  1.1046 +            sym = findField(env, site, name, site.tsym);
  1.1047 +            if (sym.exists()) return sym;
  1.1048 +            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
  1.1049 +        }
  1.1050 +
  1.1051 +        if ((kind & TYP) != 0) {
  1.1052 +            sym = findMemberType(env, site, name, site.tsym);
  1.1053 +            if (sym.exists()) return sym;
  1.1054 +            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
  1.1055 +        }
  1.1056 +        return bestSoFar;
  1.1057 +    }
  1.1058 +
  1.1059 +/* ***************************************************************************
  1.1060 + *  Access checking
  1.1061 + *  The following methods convert ResolveErrors to ErrorSymbols, issuing
  1.1062 + *  an error message in the process
  1.1063 + ****************************************************************************/
  1.1064 +
  1.1065 +    /** If `sym' is a bad symbol: report error and return errSymbol
  1.1066 +     *  else pass through unchanged,
  1.1067 +     *  additional arguments duplicate what has been used in trying to find the
  1.1068 +     *  symbol (--> flyweight pattern). This improves performance since we
  1.1069 +     *  expect misses to happen frequently.
  1.1070 +     *
  1.1071 +     *  @param sym       The symbol that was found, or a ResolveError.
  1.1072 +     *  @param pos       The position to use for error reporting.
  1.1073 +     *  @param site      The original type from where the selection took place.
  1.1074 +     *  @param name      The symbol's name.
  1.1075 +     *  @param argtypes  The invocation's value arguments,
  1.1076 +     *                   if we looked for a method.
  1.1077 +     *  @param typeargtypes  The invocation's type arguments,
  1.1078 +     *                   if we looked for a method.
  1.1079 +     */
  1.1080 +    Symbol access(Symbol sym,
  1.1081 +                  DiagnosticPosition pos,
  1.1082 +                  Type site,
  1.1083 +                  Name name,
  1.1084 +                  boolean qualified,
  1.1085 +                  List<Type> argtypes,
  1.1086 +                  List<Type> typeargtypes) {
  1.1087 +        if (sym.kind >= AMBIGUOUS) {
  1.1088 +//          printscopes(site.tsym.members());//DEBUG
  1.1089 +            if (!site.isErroneous() &&
  1.1090 +                !Type.isErroneous(argtypes) &&
  1.1091 +                (typeargtypes==null || !Type.isErroneous(typeargtypes)))
  1.1092 +                ((ResolveError)sym).report(log, pos, site, name, argtypes, typeargtypes);
  1.1093 +            do {
  1.1094 +                sym = ((ResolveError)sym).sym;
  1.1095 +            } while (sym.kind >= AMBIGUOUS);
  1.1096 +            if (sym == syms.errSymbol // preserve the symbol name through errors
  1.1097 +                || ((sym.kind & ERRONEOUS) == 0 // make sure an error symbol is returned
  1.1098 +                    && (sym.kind & TYP) != 0))
  1.1099 +                sym = new ErrorType(name, qualified?site.tsym:syms.noSymbol).tsym;
  1.1100 +        }
  1.1101 +        return sym;
  1.1102 +    }
  1.1103 +
  1.1104 +    /** Same as above, but without type arguments and arguments.
  1.1105 +     */
  1.1106 +    Symbol access(Symbol sym,
  1.1107 +                  DiagnosticPosition pos,
  1.1108 +                  Type site,
  1.1109 +                  Name name,
  1.1110 +                  boolean qualified) {
  1.1111 +        if (sym.kind >= AMBIGUOUS)
  1.1112 +            return access(sym, pos, site, name, qualified, List.<Type>nil(), null);
  1.1113 +        else
  1.1114 +            return sym;
  1.1115 +    }
  1.1116 +
  1.1117 +    /** Check that sym is not an abstract method.
  1.1118 +     */
  1.1119 +    void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
  1.1120 +        if ((sym.flags() & ABSTRACT) != 0)
  1.1121 +            log.error(pos, "abstract.cant.be.accessed.directly",
  1.1122 +                      kindName(sym), sym, sym.location());
  1.1123 +    }
  1.1124 +
  1.1125 +/* ***************************************************************************
  1.1126 + *  Debugging
  1.1127 + ****************************************************************************/
  1.1128 +
  1.1129 +    /** print all scopes starting with scope s and proceeding outwards.
  1.1130 +     *  used for debugging.
  1.1131 +     */
  1.1132 +    public void printscopes(Scope s) {
  1.1133 +        while (s != null) {
  1.1134 +            if (s.owner != null)
  1.1135 +                System.err.print(s.owner + ": ");
  1.1136 +            for (Scope.Entry e = s.elems; e != null; e = e.sibling) {
  1.1137 +                if ((e.sym.flags() & ABSTRACT) != 0)
  1.1138 +                    System.err.print("abstract ");
  1.1139 +                System.err.print(e.sym + " ");
  1.1140 +            }
  1.1141 +            System.err.println();
  1.1142 +            s = s.next;
  1.1143 +        }
  1.1144 +    }
  1.1145 +
  1.1146 +    void printscopes(Env<AttrContext> env) {
  1.1147 +        while (env.outer != null) {
  1.1148 +            System.err.println("------------------------------");
  1.1149 +            printscopes(env.info.scope);
  1.1150 +            env = env.outer;
  1.1151 +        }
  1.1152 +    }
  1.1153 +
  1.1154 +    public void printscopes(Type t) {
  1.1155 +        while (t.tag == CLASS) {
  1.1156 +            printscopes(t.tsym.members());
  1.1157 +            t = types.supertype(t);
  1.1158 +        }
  1.1159 +    }
  1.1160 +
  1.1161 +/* ***************************************************************************
  1.1162 + *  Name resolution
  1.1163 + *  Naming conventions are as for symbol lookup
  1.1164 + *  Unlike the find... methods these methods will report access errors
  1.1165 + ****************************************************************************/
  1.1166 +
  1.1167 +    /** Resolve an unqualified (non-method) identifier.
  1.1168 +     *  @param pos       The position to use for error reporting.
  1.1169 +     *  @param env       The environment current at the identifier use.
  1.1170 +     *  @param name      The identifier's name.
  1.1171 +     *  @param kind      The set of admissible symbol kinds for the identifier.
  1.1172 +     */
  1.1173 +    Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,
  1.1174 +                        Name name, int kind) {
  1.1175 +        return access(
  1.1176 +            findIdent(env, name, kind),
  1.1177 +            pos, env.enclClass.sym.type, name, false);
  1.1178 +    }
  1.1179 +
  1.1180 +    /** Resolve an unqualified method identifier.
  1.1181 +     *  @param pos       The position to use for error reporting.
  1.1182 +     *  @param env       The environment current at the method invocation.
  1.1183 +     *  @param name      The identifier's name.
  1.1184 +     *  @param argtypes  The types of the invocation's value arguments.
  1.1185 +     *  @param typeargtypes  The types of the invocation's type arguments.
  1.1186 +     */
  1.1187 +    Symbol resolveMethod(DiagnosticPosition pos,
  1.1188 +                         Env<AttrContext> env,
  1.1189 +                         Name name,
  1.1190 +                         List<Type> argtypes,
  1.1191 +                         List<Type> typeargtypes) {
  1.1192 +        Symbol sym = findFun(env, name, argtypes, typeargtypes, false, env.info.varArgs=false);
  1.1193 +        if (varargsEnabled && sym.kind >= WRONG_MTHS) {
  1.1194 +            sym = findFun(env, name, argtypes, typeargtypes, true, false);
  1.1195 +            if (sym.kind >= WRONG_MTHS)
  1.1196 +                sym = findFun(env, name, argtypes, typeargtypes, true, env.info.varArgs=true);
  1.1197 +        }
  1.1198 +        if (sym.kind >= AMBIGUOUS) {
  1.1199 +            sym = access(
  1.1200 +                sym, pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes);
  1.1201 +        }
  1.1202 +        return sym;
  1.1203 +    }
  1.1204 +
  1.1205 +    /** Resolve a qualified method identifier
  1.1206 +     *  @param pos       The position to use for error reporting.
  1.1207 +     *  @param env       The environment current at the method invocation.
  1.1208 +     *  @param site      The type of the qualifying expression, in which
  1.1209 +     *                   identifier is searched.
  1.1210 +     *  @param name      The identifier's name.
  1.1211 +     *  @param argtypes  The types of the invocation's value arguments.
  1.1212 +     *  @param typeargtypes  The types of the invocation's type arguments.
  1.1213 +     */
  1.1214 +    Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
  1.1215 +                                  Type site, Name name, List<Type> argtypes,
  1.1216 +                                  List<Type> typeargtypes) {
  1.1217 +        Symbol sym = findMethod(env, site, name, argtypes, typeargtypes, false,
  1.1218 +                                env.info.varArgs=false, false);
  1.1219 +        if (varargsEnabled && sym.kind >= WRONG_MTHS) {
  1.1220 +            sym = findMethod(env, site, name, argtypes, typeargtypes, true,
  1.1221 +                             false, false);
  1.1222 +            if (sym.kind >= WRONG_MTHS)
  1.1223 +                sym = findMethod(env, site, name, argtypes, typeargtypes, true,
  1.1224 +                                 env.info.varArgs=true, false);
  1.1225 +        }
  1.1226 +        if (sym.kind >= AMBIGUOUS) {
  1.1227 +            sym = access(sym, pos, site, name, true, argtypes, typeargtypes);
  1.1228 +        }
  1.1229 +        return sym;
  1.1230 +    }
  1.1231 +
  1.1232 +    /** Resolve a qualified method identifier, throw a fatal error if not
  1.1233 +     *  found.
  1.1234 +     *  @param pos       The position to use for error reporting.
  1.1235 +     *  @param env       The environment current at the method invocation.
  1.1236 +     *  @param site      The type of the qualifying expression, in which
  1.1237 +     *                   identifier is searched.
  1.1238 +     *  @param name      The identifier's name.
  1.1239 +     *  @param argtypes  The types of the invocation's value arguments.
  1.1240 +     *  @param typeargtypes  The types of the invocation's type arguments.
  1.1241 +     */
  1.1242 +    public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env,
  1.1243 +                                        Type site, Name name,
  1.1244 +                                        List<Type> argtypes,
  1.1245 +                                        List<Type> typeargtypes) {
  1.1246 +        Symbol sym = resolveQualifiedMethod(
  1.1247 +            pos, env, site, name, argtypes, typeargtypes);
  1.1248 +        if (sym.kind == MTH) return (MethodSymbol)sym;
  1.1249 +        else throw new FatalError(
  1.1250 +                 JCDiagnostic.fragment("fatal.err.cant.locate.meth",
  1.1251 +                                name));
  1.1252 +    }
  1.1253 +
  1.1254 +    /** Resolve constructor.
  1.1255 +     *  @param pos       The position to use for error reporting.
  1.1256 +     *  @param env       The environment current at the constructor invocation.
  1.1257 +     *  @param site      The type of class for which a constructor is searched.
  1.1258 +     *  @param argtypes  The types of the constructor invocation's value
  1.1259 +     *                   arguments.
  1.1260 +     *  @param typeargtypes  The types of the constructor invocation's type
  1.1261 +     *                   arguments.
  1.1262 +     */
  1.1263 +    Symbol resolveConstructor(DiagnosticPosition pos,
  1.1264 +                              Env<AttrContext> env,
  1.1265 +                              Type site,
  1.1266 +                              List<Type> argtypes,
  1.1267 +                              List<Type> typeargtypes) {
  1.1268 +        Symbol sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, false, env.info.varArgs=false);
  1.1269 +        if (varargsEnabled && sym.kind >= WRONG_MTHS) {
  1.1270 +            sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, true, false);
  1.1271 +            if (sym.kind >= WRONG_MTHS)
  1.1272 +                sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, true, env.info.varArgs=true);
  1.1273 +        }
  1.1274 +        if (sym.kind >= AMBIGUOUS) {
  1.1275 +            sym = access(sym, pos, site, names.init, true, argtypes, typeargtypes);
  1.1276 +        }
  1.1277 +        return sym;
  1.1278 +    }
  1.1279 +
  1.1280 +    /** Resolve constructor.
  1.1281 +     *  @param pos       The position to use for error reporting.
  1.1282 +     *  @param env       The environment current at the constructor invocation.
  1.1283 +     *  @param site      The type of class for which a constructor is searched.
  1.1284 +     *  @param argtypes  The types of the constructor invocation's value
  1.1285 +     *                   arguments.
  1.1286 +     *  @param typeargtypes  The types of the constructor invocation's type
  1.1287 +     *                   arguments.
  1.1288 +     *  @param allowBoxing Allow boxing and varargs conversions.
  1.1289 +     *  @param useVarargs Box trailing arguments into an array for varargs.
  1.1290 +     */
  1.1291 +    Symbol resolveConstructor(DiagnosticPosition pos, Env<AttrContext> env,
  1.1292 +                              Type site, List<Type> argtypes,
  1.1293 +                              List<Type> typeargtypes,
  1.1294 +                              boolean allowBoxing,
  1.1295 +                              boolean useVarargs) {
  1.1296 +        Symbol sym = findMethod(env, site,
  1.1297 +                                names.init, argtypes,
  1.1298 +                                typeargtypes, allowBoxing,
  1.1299 +                                useVarargs, false);
  1.1300 +        if ((sym.flags() & DEPRECATED) != 0 &&
  1.1301 +            (env.info.scope.owner.flags() & DEPRECATED) == 0 &&
  1.1302 +            env.info.scope.owner.outermostClass() != sym.outermostClass())
  1.1303 +            chk.warnDeprecated(pos, sym);
  1.1304 +        return sym;
  1.1305 +    }
  1.1306 +
  1.1307 +    /** Resolve a constructor, throw a fatal error if not found.
  1.1308 +     *  @param pos       The position to use for error reporting.
  1.1309 +     *  @param env       The environment current at the method invocation.
  1.1310 +     *  @param site      The type to be constructed.
  1.1311 +     *  @param argtypes  The types of the invocation's value arguments.
  1.1312 +     *  @param typeargtypes  The types of the invocation's type arguments.
  1.1313 +     */
  1.1314 +    public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
  1.1315 +                                        Type site,
  1.1316 +                                        List<Type> argtypes,
  1.1317 +                                        List<Type> typeargtypes) {
  1.1318 +        Symbol sym = resolveConstructor(
  1.1319 +            pos, env, site, argtypes, typeargtypes);
  1.1320 +        if (sym.kind == MTH) return (MethodSymbol)sym;
  1.1321 +        else throw new FatalError(
  1.1322 +                 JCDiagnostic.fragment("fatal.err.cant.locate.ctor", site));
  1.1323 +    }
  1.1324 +
  1.1325 +    /** Resolve operator.
  1.1326 +     *  @param pos       The position to use for error reporting.
  1.1327 +     *  @param optag     The tag of the operation tree.
  1.1328 +     *  @param env       The environment current at the operation.
  1.1329 +     *  @param argtypes  The types of the operands.
  1.1330 +     */
  1.1331 +    Symbol resolveOperator(DiagnosticPosition pos, int optag,
  1.1332 +                           Env<AttrContext> env, List<Type> argtypes) {
  1.1333 +        Name name = treeinfo.operatorName(optag);
  1.1334 +        Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
  1.1335 +                                null, false, false, true);
  1.1336 +        if (boxingEnabled && sym.kind >= WRONG_MTHS)
  1.1337 +            sym = findMethod(env, syms.predefClass.type, name, argtypes,
  1.1338 +                             null, true, false, true);
  1.1339 +        return access(sym, pos, env.enclClass.sym.type, name,
  1.1340 +                      false, argtypes, null);
  1.1341 +    }
  1.1342 +
  1.1343 +    /** Resolve operator.
  1.1344 +     *  @param pos       The position to use for error reporting.
  1.1345 +     *  @param optag     The tag of the operation tree.
  1.1346 +     *  @param env       The environment current at the operation.
  1.1347 +     *  @param arg       The type of the operand.
  1.1348 +     */
  1.1349 +    Symbol resolveUnaryOperator(DiagnosticPosition pos, int optag, Env<AttrContext> env, Type arg) {
  1.1350 +        return resolveOperator(pos, optag, env, List.of(arg));
  1.1351 +    }
  1.1352 +
  1.1353 +    /** Resolve binary operator.
  1.1354 +     *  @param pos       The position to use for error reporting.
  1.1355 +     *  @param optag     The tag of the operation tree.
  1.1356 +     *  @param env       The environment current at the operation.
  1.1357 +     *  @param left      The types of the left operand.
  1.1358 +     *  @param right     The types of the right operand.
  1.1359 +     */
  1.1360 +    Symbol resolveBinaryOperator(DiagnosticPosition pos,
  1.1361 +                                 int optag,
  1.1362 +                                 Env<AttrContext> env,
  1.1363 +                                 Type left,
  1.1364 +                                 Type right) {
  1.1365 +        return resolveOperator(pos, optag, env, List.of(left, right));
  1.1366 +    }
  1.1367 +
  1.1368 +    /**
  1.1369 +     * Resolve `c.name' where name == this or name == super.
  1.1370 +     * @param pos           The position to use for error reporting.
  1.1371 +     * @param env           The environment current at the expression.
  1.1372 +     * @param c             The qualifier.
  1.1373 +     * @param name          The identifier's name.
  1.1374 +     */
  1.1375 +    Symbol resolveSelf(DiagnosticPosition pos,
  1.1376 +                       Env<AttrContext> env,
  1.1377 +                       TypeSymbol c,
  1.1378 +                       Name name) {
  1.1379 +        Env<AttrContext> env1 = env;
  1.1380 +        boolean staticOnly = false;
  1.1381 +        while (env1.outer != null) {
  1.1382 +            if (isStatic(env1)) staticOnly = true;
  1.1383 +            if (env1.enclClass.sym == c) {
  1.1384 +                Symbol sym = env1.info.scope.lookup(name).sym;
  1.1385 +                if (sym != null) {
  1.1386 +                    if (staticOnly) sym = new StaticError(sym);
  1.1387 +                    return access(sym, pos, env.enclClass.sym.type,
  1.1388 +                                  name, true);
  1.1389 +                }
  1.1390 +            }
  1.1391 +            if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
  1.1392 +            env1 = env1.outer;
  1.1393 +        }
  1.1394 +        log.error(pos, "not.encl.class", c);
  1.1395 +        return syms.errSymbol;
  1.1396 +    }
  1.1397 +
  1.1398 +    /**
  1.1399 +     * Resolve `c.this' for an enclosing class c that contains the
  1.1400 +     * named member.
  1.1401 +     * @param pos           The position to use for error reporting.
  1.1402 +     * @param env           The environment current at the expression.
  1.1403 +     * @param member        The member that must be contained in the result.
  1.1404 +     */
  1.1405 +    Symbol resolveSelfContaining(DiagnosticPosition pos,
  1.1406 +                                 Env<AttrContext> env,
  1.1407 +                                 Symbol member) {
  1.1408 +        Name name = names._this;
  1.1409 +        Env<AttrContext> env1 = env;
  1.1410 +        boolean staticOnly = false;
  1.1411 +        while (env1.outer != null) {
  1.1412 +            if (isStatic(env1)) staticOnly = true;
  1.1413 +            if (env1.enclClass.sym.isSubClass(member.owner, types) &&
  1.1414 +                isAccessible(env, env1.enclClass.sym.type, member)) {
  1.1415 +                Symbol sym = env1.info.scope.lookup(name).sym;
  1.1416 +                if (sym != null) {
  1.1417 +                    if (staticOnly) sym = new StaticError(sym);
  1.1418 +                    return access(sym, pos, env.enclClass.sym.type,
  1.1419 +                                  name, true);
  1.1420 +                }
  1.1421 +            }
  1.1422 +            if ((env1.enclClass.sym.flags() & STATIC) != 0)
  1.1423 +                staticOnly = true;
  1.1424 +            env1 = env1.outer;
  1.1425 +        }
  1.1426 +        log.error(pos, "encl.class.required", member);
  1.1427 +        return syms.errSymbol;
  1.1428 +    }
  1.1429 +
  1.1430 +    /**
  1.1431 +     * Resolve an appropriate implicit this instance for t's container.
  1.1432 +     * JLS2 8.8.5.1 and 15.9.2
  1.1433 +     */
  1.1434 +    Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) {
  1.1435 +        Type thisType = (((t.tsym.owner.kind & (MTH|VAR)) != 0)
  1.1436 +                         ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this)
  1.1437 +                         : resolveSelfContaining(pos, env, t.tsym)).type;
  1.1438 +        if (env.info.isSelfCall && thisType.tsym == env.enclClass.sym)
  1.1439 +            log.error(pos, "cant.ref.before.ctor.called", "this");
  1.1440 +        return thisType;
  1.1441 +    }
  1.1442 +
  1.1443 +/* ***************************************************************************
  1.1444 + *  Methods related to kinds
  1.1445 + ****************************************************************************/
  1.1446 +
  1.1447 +    /** A localized string describing a given kind.
  1.1448 +     */
  1.1449 +    static JCDiagnostic kindName(int kind) {
  1.1450 +        switch (kind) {
  1.1451 +        case PCK: return JCDiagnostic.fragment("kindname.package");
  1.1452 +        case TYP: return JCDiagnostic.fragment("kindname.class");
  1.1453 +        case VAR: return JCDiagnostic.fragment("kindname.variable");
  1.1454 +        case VAL: return JCDiagnostic.fragment("kindname.value");
  1.1455 +        case MTH: return JCDiagnostic.fragment("kindname.method");
  1.1456 +        default : return JCDiagnostic.fragment("kindname",
  1.1457 +                                               Integer.toString(kind)); //debug
  1.1458 +        }
  1.1459 +    }
  1.1460 +
  1.1461 +    static JCDiagnostic kindName(Symbol sym) {
  1.1462 +        switch (sym.getKind()) {
  1.1463 +        case PACKAGE:
  1.1464 +            return JCDiagnostic.fragment("kindname.package");
  1.1465 +
  1.1466 +        case ENUM:
  1.1467 +        case ANNOTATION_TYPE:
  1.1468 +        case INTERFACE:
  1.1469 +        case CLASS:
  1.1470 +            return JCDiagnostic.fragment("kindname.class");
  1.1471 +
  1.1472 +        case TYPE_PARAMETER:
  1.1473 +            return JCDiagnostic.fragment("kindname.type.variable");
  1.1474 +
  1.1475 +        case ENUM_CONSTANT:
  1.1476 +        case FIELD:
  1.1477 +        case PARAMETER:
  1.1478 +        case LOCAL_VARIABLE:
  1.1479 +        case EXCEPTION_PARAMETER:
  1.1480 +            return JCDiagnostic.fragment("kindname.variable");
  1.1481 +
  1.1482 +        case METHOD:
  1.1483 +        case CONSTRUCTOR:
  1.1484 +        case STATIC_INIT:
  1.1485 +        case INSTANCE_INIT:
  1.1486 +            return JCDiagnostic.fragment("kindname.method");
  1.1487 +
  1.1488 +        default:
  1.1489 +            if (sym.kind == VAL)
  1.1490 +                // I don't think this can happen but it can't harm
  1.1491 +                // playing it safe --ahe
  1.1492 +                return JCDiagnostic.fragment("kindname.value");
  1.1493 +            else
  1.1494 +                return JCDiagnostic.fragment("kindname", sym.getKind()); // debug
  1.1495 +        }
  1.1496 +    }
  1.1497 +
  1.1498 +    /** A localized string describing a given set of kinds.
  1.1499 +     */
  1.1500 +    static JCDiagnostic kindNames(int kind) {
  1.1501 +        StringBuffer key = new StringBuffer();
  1.1502 +        key.append("kindname");
  1.1503 +        if ((kind & VAL) != 0)
  1.1504 +            key.append(((kind & VAL) == VAR) ? ".variable" : ".value");
  1.1505 +        if ((kind & MTH) != 0) key.append(".method");
  1.1506 +        if ((kind & TYP) != 0) key.append(".class");
  1.1507 +        if ((kind & PCK) != 0) key.append(".package");
  1.1508 +        return JCDiagnostic.fragment(key.toString(), kind);
  1.1509 +    }
  1.1510 +
  1.1511 +    /** A localized string describing the kind -- either class or interface --
  1.1512 +     *  of a given type.
  1.1513 +     */
  1.1514 +    static JCDiagnostic typeKindName(Type t) {
  1.1515 +        if (t.tag == TYPEVAR ||
  1.1516 +            t.tag == CLASS && (t.tsym.flags() & COMPOUND) != 0)
  1.1517 +            return JCDiagnostic.fragment("kindname.type.variable.bound");
  1.1518 +        else if (t.tag == PACKAGE)
  1.1519 +            return JCDiagnostic.fragment("kindname.package");
  1.1520 +        else if ((t.tsym.flags_field & ANNOTATION) != 0)
  1.1521 +            return JCDiagnostic.fragment("kindname.annotation");
  1.1522 +        else if ((t.tsym.flags_field & INTERFACE) != 0)
  1.1523 +            return JCDiagnostic.fragment("kindname.interface");
  1.1524 +        else
  1.1525 +            return JCDiagnostic.fragment("kindname.class");
  1.1526 +    }
  1.1527 +
  1.1528 +    /** A localized string describing the kind of a missing symbol, given an
  1.1529 +     *  error kind.
  1.1530 +     */
  1.1531 +    static JCDiagnostic absentKindName(int kind) {
  1.1532 +        switch (kind) {
  1.1533 +        case ABSENT_VAR:
  1.1534 +            return JCDiagnostic.fragment("kindname.variable");
  1.1535 +        case WRONG_MTHS: case WRONG_MTH: case ABSENT_MTH:
  1.1536 +            return JCDiagnostic.fragment("kindname.method");
  1.1537 +        case ABSENT_TYP:
  1.1538 +            return JCDiagnostic.fragment("kindname.class");
  1.1539 +        default:
  1.1540 +            return JCDiagnostic.fragment("kindname", kind);
  1.1541 +        }
  1.1542 +    }
  1.1543 +
  1.1544 +/* ***************************************************************************
  1.1545 + *  ResolveError classes, indicating error situations when accessing symbols
  1.1546 + ****************************************************************************/
  1.1547 +
  1.1548 +    public void logAccessError(Env<AttrContext> env, JCTree tree, Type type) {
  1.1549 +        AccessError error = new AccessError(env, type.getEnclosingType(), type.tsym);
  1.1550 +        error.report(log, tree.pos(), type.getEnclosingType(), null, null, null);
  1.1551 +    }
  1.1552 +
  1.1553 +    /** Root class for resolve errors.
  1.1554 +     *  Instances of this class indicate "Symbol not found".
  1.1555 +     *  Instances of subclass indicate other errors.
  1.1556 +     */
  1.1557 +    private class ResolveError extends Symbol {
  1.1558 +
  1.1559 +        ResolveError(int kind, Symbol sym, String debugName) {
  1.1560 +            super(kind, 0, null, null, null);
  1.1561 +            this.debugName = debugName;
  1.1562 +            this.sym = sym;
  1.1563 +        }
  1.1564 +
  1.1565 +        /** The name of the kind of error, for debugging only.
  1.1566 +         */
  1.1567 +        final String debugName;
  1.1568 +
  1.1569 +        /** The symbol that was determined by resolution, or errSymbol if none
  1.1570 +         *  was found.
  1.1571 +         */
  1.1572 +        final Symbol sym;
  1.1573 +
  1.1574 +        /** The symbol that was a close mismatch, or null if none was found.
  1.1575 +         *  wrongSym is currently set if a simgle method with the correct name, but
  1.1576 +         *  the wrong parameters was found.
  1.1577 +         */
  1.1578 +        Symbol wrongSym;
  1.1579 +
  1.1580 +        /** An auxiliary explanation set in case of instantiation errors.
  1.1581 +         */
  1.1582 +        JCDiagnostic explanation;
  1.1583 +
  1.1584 +
  1.1585 +        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
  1.1586 +            throw new AssertionError();
  1.1587 +        }
  1.1588 +
  1.1589 +        /** Print the (debug only) name of the kind of error.
  1.1590 +         */
  1.1591 +        public String toString() {
  1.1592 +            return debugName + " wrongSym=" + wrongSym + " explanation=" + explanation;
  1.1593 +        }
  1.1594 +
  1.1595 +        /** Update wrongSym and explanation and return this.
  1.1596 +         */
  1.1597 +        ResolveError setWrongSym(Symbol sym, JCDiagnostic explanation) {
  1.1598 +            this.wrongSym = sym;
  1.1599 +            this.explanation = explanation;
  1.1600 +            return this;
  1.1601 +        }
  1.1602 +
  1.1603 +        /** Update wrongSym and return this.
  1.1604 +         */
  1.1605 +        ResolveError setWrongSym(Symbol sym) {
  1.1606 +            this.wrongSym = sym;
  1.1607 +            this.explanation = null;
  1.1608 +            return this;
  1.1609 +        }
  1.1610 +
  1.1611 +        public boolean exists() {
  1.1612 +            switch (kind) {
  1.1613 +            case HIDDEN:
  1.1614 +            case ABSENT_VAR:
  1.1615 +            case ABSENT_MTH:
  1.1616 +            case ABSENT_TYP:
  1.1617 +                return false;
  1.1618 +            default:
  1.1619 +                return true;
  1.1620 +            }
  1.1621 +        }
  1.1622 +
  1.1623 +        /** Report error.
  1.1624 +         *  @param log       The error log to be used for error reporting.
  1.1625 +         *  @param pos       The position to be used for error reporting.
  1.1626 +         *  @param site      The original type from where the selection took place.
  1.1627 +         *  @param name      The name of the symbol to be resolved.
  1.1628 +         *  @param argtypes  The invocation's value arguments,
  1.1629 +         *                   if we looked for a method.
  1.1630 +         *  @param typeargtypes  The invocation's type arguments,
  1.1631 +         *                   if we looked for a method.
  1.1632 +         */
  1.1633 +        void report(Log log, DiagnosticPosition pos, Type site, Name name,
  1.1634 +                    List<Type> argtypes, List<Type> typeargtypes) {
  1.1635 +            if (name != name.table.error) {
  1.1636 +                JCDiagnostic kindname = absentKindName(kind);
  1.1637 +                String idname = name.toString();
  1.1638 +                String args = "";
  1.1639 +                String typeargs = "";
  1.1640 +                if (kind >= WRONG_MTHS && kind <= ABSENT_MTH) {
  1.1641 +                    if (isOperator(name)) {
  1.1642 +                        log.error(pos, "operator.cant.be.applied",
  1.1643 +                                  name, Type.toString(argtypes));
  1.1644 +                        return;
  1.1645 +                    }
  1.1646 +                    if (name == name.table.init) {
  1.1647 +                        kindname = JCDiagnostic.fragment("kindname.constructor");
  1.1648 +                        idname = site.tsym.name.toString();
  1.1649 +                    }
  1.1650 +                    args = "(" + Type.toString(argtypes) + ")";
  1.1651 +                    if (typeargtypes != null && typeargtypes.nonEmpty())
  1.1652 +                        typeargs = "<" + Type.toString(typeargtypes) + ">";
  1.1653 +                }
  1.1654 +                if (kind == WRONG_MTH) {
  1.1655 +                    log.error(pos,
  1.1656 +                              "cant.apply.symbol" + (explanation != null ? ".1" : ""),
  1.1657 +                              wrongSym.asMemberOf(site, types),
  1.1658 +                              wrongSym.location(site, types),
  1.1659 +                              typeargs,
  1.1660 +                              Type.toString(argtypes),
  1.1661 +                              explanation);
  1.1662 +                } else if (site.tsym.name.len != 0) {
  1.1663 +                    if (site.tsym.kind == PCK && !site.tsym.exists())
  1.1664 +                        log.error(pos, "doesnt.exist", site.tsym);
  1.1665 +                    else
  1.1666 +                        log.error(pos, "cant.resolve.location",
  1.1667 +                                  kindname, idname, args, typeargs,
  1.1668 +                                  typeKindName(site), site);
  1.1669 +                } else {
  1.1670 +                    log.error(pos, "cant.resolve", kindname, idname, args, typeargs);
  1.1671 +                }
  1.1672 +            }
  1.1673 +        }
  1.1674 +//where
  1.1675 +            /** A name designates an operator if it consists
  1.1676 +             *  of a non-empty sequence of operator symbols +-~!/*%&|^<>=
  1.1677 +             */
  1.1678 +            boolean isOperator(Name name) {
  1.1679 +                int i = 0;
  1.1680 +                while (i < name.len &&
  1.1681 +                       "+-~!*/%&|^<>=".indexOf(name.byteAt(i)) >= 0) i++;
  1.1682 +                return i > 0 && i == name.len;
  1.1683 +            }
  1.1684 +    }
  1.1685 +
  1.1686 +    /** Resolve error class indicating that a symbol is not accessible.
  1.1687 +     */
  1.1688 +    class AccessError extends ResolveError {
  1.1689 +
  1.1690 +        AccessError(Symbol sym) {
  1.1691 +            this(null, null, sym);
  1.1692 +        }
  1.1693 +
  1.1694 +        AccessError(Env<AttrContext> env, Type site, Symbol sym) {
  1.1695 +            super(HIDDEN, sym, "access error");
  1.1696 +            this.env = env;
  1.1697 +            this.site = site;
  1.1698 +            if (debugResolve)
  1.1699 +                log.error("proc.messager", sym + " @ " + site + " is inaccessible.");
  1.1700 +        }
  1.1701 +
  1.1702 +        private Env<AttrContext> env;
  1.1703 +        private Type site;
  1.1704 +
  1.1705 +        /** Report error.
  1.1706 +         *  @param log       The error log to be used for error reporting.
  1.1707 +         *  @param pos       The position to be used for error reporting.
  1.1708 +         *  @param site      The original type from where the selection took place.
  1.1709 +         *  @param name      The name of the symbol to be resolved.
  1.1710 +         *  @param argtypes  The invocation's value arguments,
  1.1711 +         *                   if we looked for a method.
  1.1712 +         *  @param typeargtypes  The invocation's type arguments,
  1.1713 +         *                   if we looked for a method.
  1.1714 +         */
  1.1715 +        void report(Log log, DiagnosticPosition pos, Type site, Name name,
  1.1716 +                    List<Type> argtypes, List<Type> typeargtypes) {
  1.1717 +            if (sym.owner.type.tag != ERROR) {
  1.1718 +                if (sym.name == sym.name.table.init && sym.owner != site.tsym)
  1.1719 +                    new ResolveError(ABSENT_MTH, sym.owner, "absent method " + sym).report(
  1.1720 +                        log, pos, site, name, argtypes, typeargtypes);
  1.1721 +                if ((sym.flags() & PUBLIC) != 0
  1.1722 +                    || (env != null && this.site != null
  1.1723 +                        && !isAccessible(env, this.site)))
  1.1724 +                    log.error(pos, "not.def.access.class.intf.cant.access",
  1.1725 +                        sym, sym.location());
  1.1726 +                else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0)
  1.1727 +                    log.error(pos, "report.access", sym,
  1.1728 +                              TreeInfo.flagNames(sym.flags() & (PRIVATE | PROTECTED)),
  1.1729 +                              sym.location());
  1.1730 +                else
  1.1731 +                    log.error(pos, "not.def.public.cant.access",
  1.1732 +                              sym, sym.location());
  1.1733 +            }
  1.1734 +        }
  1.1735 +    }
  1.1736 +
  1.1737 +    /** Resolve error class indicating that an instance member was accessed
  1.1738 +     *  from a static context.
  1.1739 +     */
  1.1740 +    class StaticError extends ResolveError {
  1.1741 +        StaticError(Symbol sym) {
  1.1742 +            super(STATICERR, sym, "static error");
  1.1743 +        }
  1.1744 +
  1.1745 +        /** Report error.
  1.1746 +         *  @param log       The error log to be used for error reporting.
  1.1747 +         *  @param pos       The position to be used for error reporting.
  1.1748 +         *  @param site      The original type from where the selection took place.
  1.1749 +         *  @param name      The name of the symbol to be resolved.
  1.1750 +         *  @param argtypes  The invocation's value arguments,
  1.1751 +         *                   if we looked for a method.
  1.1752 +         *  @param typeargtypes  The invocation's type arguments,
  1.1753 +         *                   if we looked for a method.
  1.1754 +         */
  1.1755 +        void report(Log log,
  1.1756 +                    DiagnosticPosition pos,
  1.1757 +                    Type site,
  1.1758 +                    Name name,
  1.1759 +                    List<Type> argtypes,
  1.1760 +                    List<Type> typeargtypes) {
  1.1761 +            String symstr = ((sym.kind == TYP && sym.type.tag == CLASS)
  1.1762 +                ? types.erasure(sym.type)
  1.1763 +                : sym).toString();
  1.1764 +            log.error(pos, "non-static.cant.be.ref",
  1.1765 +                      kindName(sym), symstr);
  1.1766 +        }
  1.1767 +    }
  1.1768 +
  1.1769 +    /** Resolve error class indicating an ambiguous reference.
  1.1770 +     */
  1.1771 +    class AmbiguityError extends ResolveError {
  1.1772 +        Symbol sym1;
  1.1773 +        Symbol sym2;
  1.1774 +
  1.1775 +        AmbiguityError(Symbol sym1, Symbol sym2) {
  1.1776 +            super(AMBIGUOUS, sym1, "ambiguity error");
  1.1777 +            this.sym1 = sym1;
  1.1778 +            this.sym2 = sym2;
  1.1779 +        }
  1.1780 +
  1.1781 +        /** Report error.
  1.1782 +         *  @param log       The error log to be used for error reporting.
  1.1783 +         *  @param pos       The position to be used for error reporting.
  1.1784 +         *  @param site      The original type from where the selection took place.
  1.1785 +         *  @param name      The name of the symbol to be resolved.
  1.1786 +         *  @param argtypes  The invocation's value arguments,
  1.1787 +         *                   if we looked for a method.
  1.1788 +         *  @param typeargtypes  The invocation's type arguments,
  1.1789 +         *                   if we looked for a method.
  1.1790 +         */
  1.1791 +        void report(Log log, DiagnosticPosition pos, Type site, Name name,
  1.1792 +                    List<Type> argtypes, List<Type> typeargtypes) {
  1.1793 +            AmbiguityError pair = this;
  1.1794 +            while (true) {
  1.1795 +                if (pair.sym1.kind == AMBIGUOUS)
  1.1796 +                    pair = (AmbiguityError)pair.sym1;
  1.1797 +                else if (pair.sym2.kind == AMBIGUOUS)
  1.1798 +                    pair = (AmbiguityError)pair.sym2;
  1.1799 +                else break;
  1.1800 +            }
  1.1801 +            Name sname = pair.sym1.name;
  1.1802 +            if (sname == sname.table.init) sname = pair.sym1.owner.name;
  1.1803 +            log.error(pos, "ref.ambiguous", sname,
  1.1804 +                      kindName(pair.sym1),
  1.1805 +                      pair.sym1,
  1.1806 +                      pair.sym1.location(site, types),
  1.1807 +                      kindName(pair.sym2),
  1.1808 +                      pair.sym2,
  1.1809 +                      pair.sym2.location(site, types));
  1.1810 +        }
  1.1811 +    }
  1.1812 +}

mercurial