⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 resolve.java

📁 GJC(Generic Java Compiler)编译器
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/** * @(#)Resolve.java	1.67 03/05/06 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.tools.javac.v8.comp;import com.sun.tools.javac.v8.util.*;import com.sun.tools.javac.v8.code.*;import com.sun.tools.javac.v8.tree.*;import com.sun.tools.javac.v8.code.Type.*;import com.sun.tools.javac.v8.code.Symbol.*;import com.sun.tools.javac.v8.tree.Tree.*;/** * Helper class for name resolution, used mostly by the attribution phase. */public class Resolve implements Flags, Kinds, TypeTags {    private static final Context.Key resolveKey = new Context.Key();    private Name.Table names;    private Log log;    private Symtab syms;    private Check chk;    private Infer infer;    private ClassReader reader;    private TreeInfo treeinfo;    public static Resolve instance(Context context) {        Resolve instance = (Resolve) context.get(resolveKey);        if (instance == null)            instance = new Resolve(context);        return instance;    }    private Resolve(Context context) {        super();        context.put(resolveKey, this);        syms = Symtab.instance(context);        varNotFound = new ResolveError(ABSENT_VAR, syms.errSymbol, "variable not found");        wrongMethod = new ResolveError(WRONG_MTH, syms.errSymbol, "method not found");        wrongMethods = new ResolveError(WRONG_MTHS, syms.errSymbol, "wrong methods");        methodNotFound = new ResolveError(ABSENT_MTH, syms.errSymbol, "method not found");        typeNotFound = new ResolveError(ABSENT_TYP, syms.errSymbol, "type not found");        names = Name.Table.instance(context);        log = Log.instance(context);        chk = Check.instance(context);        infer = Infer.instance(context);        reader = ClassReader.instance(context);        treeinfo = TreeInfo.instance(context);    }    /**      * Error kinds that complement the constants in Kinds      */    static final int AMBIGUOUS = 256;    static final int HIDDEN = 257;    static final int ABSENT_VAR = 258;    static final int WRONG_MTHS = 259;    static final int WRONG_MTH = 260;    static final int ABSENT_MTH = 261;    static final int ABSENT_TYP = 262;    /**     * error symbols, which are returned when resolution fails     */    final ResolveError varNotFound;    final ResolveError wrongMethod;    final ResolveError wrongMethods;    final ResolveError methodNotFound;    final ResolveError typeNotFound;    /**     * An environment is "static" if its static level is greater than     *  the one of its outer environment     */    static boolean isStatic(Env env) {        return ((AttrContext) env.info).staticLevel >                ((AttrContext) env.outer.info).staticLevel;    }    /**      * The static level of a symbol is the number of prefixing static flags      *  for the symbol and any enclosing class or member declarations.      */    static int staticLevel(Symbol sym) {        int level = 0;        do {            if ((sym.flags() & STATIC) != 0)                level++;            sym = sym.owner;        } while (sym.kind != PCK)            ;        return level;    }    /**      * Is class accessible in given evironment?      *  @param env    The current environment.      *  @param c      The class whose accessibility is checked.      */    boolean isAccessible(Env env, TypeSymbol c) {        switch ((short)(c.flags() & AccessFlags)) {        case PRIVATE:            return env.enclClass.sym.outermostClass() == c.owner.outermostClass();        case 0:            return env.toplevel.packge == c.owner ||                    env.toplevel.packge == c.packge() || env.enclMethod != null &&                    (env.enclMethod.flags & ANONCONSTR) != 0;        case PUBLIC:            return true;        case PROTECTED:            return env.toplevel.packge == c.owner ||                    env.toplevel.packge == c.packge() ||                    isInnerSubClass(env.enclClass.sym, c.owner);        default:            return true;        }    }    /**      * Is given class a subclass of given base class, or an inner class      *  of a subclass?      *  Return null if no such class exists.      *  @param c     The class which is the subclass or is contained in it.      *  @param base  The base class      */    private boolean isInnerSubClass(ClassSymbol c, Symbol base) {        while (c != null && !c.isSubClass(base)) {            c = c.owner.enclClass();        }        return c != null;    }    boolean isAccessible(Env env, Type t) {        return (t.tag == ARRAY) ? isAccessible(env, t.elemtype()) :                isAccessible(env, t.tsym);    }    /**      * Is symbol accessible as a member of given type in given evironment?      *  @param env    The current environment.      *  @param site   The type of which the tested symbol is regarded      *                as a member.      *  @param sym    The symbol.      */    boolean isAccessible(Env env, Type site, Symbol sym) {        if (sym.name == names.init && sym.owner != site.tsym)            return false;        ClassSymbol sub;        switch ((short)(sym.flags() & AccessFlags)) {        case PRIVATE:            return (env.enclClass.sym == sym.owner ||                    env.enclClass.sym.outermostClass() ==                    sym.owner.outermostClass()) && sym.isInheritedIn(site.tsym);        case 0:            return (env.toplevel.packge == sym.owner.owner ||                    env.toplevel.packge == sym.packge()) &&                    sym.isInheritedIn(site.tsym);        case PROTECTED:            return (env.toplevel.packge == sym.owner.owner ||                    env.toplevel.packge == sym.packge() ||                    isProtectedAccessible(sym, env.enclClass.sym, site) ||                    ((AttrContext) env.info).selectSuper &&                    (sym.flags() & STATIC) == 0 && sym.kind != TYP) &&                    (sym.kind != MTH || sym.isConstructor() ||                    ((MethodSymbol) sym).implementation(site.tsym) == sym);        default:            return isAccessible(env, site);        }    }    /**      * Is given protected symbol accessible if it is selected from given site      *  and the selection takes place in given class?      *  @param sym     The symbol with protected access      *  @param c       The class where the access takes place      *  @site          The type of the qualifier      */    private boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) {        while (c != null &&                !(c.isSubClass(sym.owner) && (c.flags() & INTERFACE) == 0 &&                ((sym.flags() & STATIC) != 0 || sym.kind == TYP ||                site.tsym.isSubClass(c))))            c = c.owner.enclClass();        return c != null;    }    /**      * Try to instantiate the type of a method so that it fits      *  given type parameters and argument types. If succesful, return      *  the method's instantiated type, else return null.      *  The instantiation will take into account an additional leading      *  formal parameter if the method is an instance method seen as a member      *  of un underdetermined site In this case, we treat site as an additional      *  parameter and the parameters of the class containing the method as      *  additional type variables that get instantiated.      *      *  @param env         The current environment      *  @param site        The type of which the method is a member.      *  @param m           The method symbol.      *  @param argtypes    The invocation's given value parameters.      */    Type instantiate(Env env, Type site, Symbol m, List argtypes) {        Type mt = site.memberType(m);        List formals = mt.argtypes();        return (Type.isSubTypes(argtypes, formals)) ? mt : null;    }    /**      * Find field. Synthetic fields are always skipped.      *  @param env     The current environment.      *  @param site    The original type from where the selection takes place.      *  @param name    The name of the field.      *  @param c       The class to search for the field. This is always      *                 a superclass or implemented interface of site's class.      */    Symbol findField(Env env, Type site, Name name, TypeSymbol c) {        Symbol bestSoFar = varNotFound;        Symbol sym;        Scope.Entry e = c.members().lookup(name);        while (e.scope != null) {            if (e.sym.kind == VAR && (e.sym.flags_field & SYNTHETIC) == 0) {                if (isAccessible(env, site, e.sym))                    return e.sym;                else                    return new AccessError(e.sym);            }            e = e.next();        }        Type st = c.type.supertype();        if (st != null && st.tag == CLASS) {            sym = findField(env, site, name, st.tsym);            if (sym.kind < bestSoFar.kind)                bestSoFar = sym;        }        for (List l = c.type.interfaces();                bestSoFar.kind != AMBIGUOUS && l.nonEmpty(); l = l.tail) {            sym = findField(env, site, name, ((Type) l.head).tsym);            if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&                    sym.owner != bestSoFar.owner)                bestSoFar = new AmbiguityError(bestSoFar, sym);            else if (sym.kind < bestSoFar.kind)                bestSoFar = sym;        }        return bestSoFar;    }    /**      * Find unqualified variable or field with given name.      *  Synthetic fields always skipped.      *  @param env     The current environment.      *  @param name    The name of the variable or field.      */    Symbol findVar(Env env, Name name) {        Symbol bestSoFar = varNotFound;        Symbol sym;        Env env1 = env;        boolean staticOnly = false;        while (env1.outer != null) {            if (isStatic(env1))                staticOnly = true;            Scope.Entry e = ((AttrContext) env1.info).scope.lookup(name);            while (e.scope != null &&                    (e.sym.kind != VAR || (e.sym.flags_field & SYNTHETIC) != 0))                e = e.next();            sym = (e.scope != null) ? e.sym :                    findField(env1, env1.enclClass.sym.type, name,                    env1.enclClass.sym);            if (sym.kind <= AMBIGUOUS) {                if (staticOnly && sym.kind == VAR && sym.owner.kind == TYP &&                        (sym.flags() & STATIC) == 0)                    return new StaticError(sym);                else                    return sym;            } else if (sym.kind < bestSoFar.kind) {                bestSoFar = sym;            }            if ((env1.enclClass.sym.flags() & STATIC) != 0)                staticOnly = true;            env1 = env1.outer;        }        sym = findField(env, syms.predefClass.type, name, syms.predefClass);        if (sym.kind <= AMBIGUOUS)            return sym;        else            return bestSoFar;    }    /**      * Select the best method for a call site among two choices.      *  @param env		The current environment.      *  @param site		The original type from where the selection takes place.      *  @param argtypes		The invocation's value parameters,      *  @param sym		Proposed new best match.      *  @param bestSoFar	Previously found best match.      */    Symbol selectBest(Env env, Type site, List argtypes, Symbol sym,            Symbol bestSoFar) {        if (sym.kind == ERR)            return bestSoFar;        assert sym.kind < AMBIGUOUS;        if (instantiate(env, site, sym, argtypes) == null) {            switch (bestSoFar.kind) {            case ABSENT_MTH:                return wrongMethod.setWrongSym(sym);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -