memberenter.java

来自「是一款用JAVA 编写的编译器 具有很强的编译功能」· Java 代码 · 共 1,108 行 · 第 1/3 页

JAVA
1,108
字号
/* * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */package com.sun.tools.javac.comp;import java.util.*;import java.util.Set;import javax.tools.JavaFileObject;import com.sun.tools.javac.code.*;import com.sun.tools.javac.jvm.*;import com.sun.tools.javac.tree.*;import com.sun.tools.javac.util.*;import com.sun.tools.javac.util.List;import com.sun.tools.javac.code.Type.*;import com.sun.tools.javac.code.Symbol.*;import com.sun.tools.javac.tree.JCTree.*;import static com.sun.tools.javac.code.Flags.*;import static com.sun.tools.javac.code.Kinds.*;import static com.sun.tools.javac.code.TypeTags.*;import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;/** This is the second phase of Enter, in which classes are completed *  by entering their members into the class scope using *  MemberEnter.complete().  See Enter for an overview. * *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If *  you write code that depends on this, you do so at your own risk. *  This code and its internal interfaces are subject to change or *  deletion without notice.</b> */public class MemberEnter extends JCTree.Visitor implements Completer {    protected static final Context.Key<MemberEnter> memberEnterKey =        new Context.Key<MemberEnter>();    /** A switch to determine whether we check for package/class conflicts     */    final static boolean checkClash = true;    private final Name.Table names;    private final Enter enter;    private final Log log;    private final Check chk;    private final Attr attr;    private final Symtab syms;    private final TreeMaker make;    private final ClassReader reader;    private final Todo todo;    private final Annotate annotate;    private final Types types;    private final Target target;    private final boolean skipAnnotations;    public static MemberEnter instance(Context context) {        MemberEnter instance = context.get(memberEnterKey);        if (instance == null)            instance = new MemberEnter(context);        return instance;    }    protected MemberEnter(Context context) {        context.put(memberEnterKey, this);        names = Name.Table.instance(context);        enter = Enter.instance(context);        log = Log.instance(context);        chk = Check.instance(context);        attr = Attr.instance(context);        syms = Symtab.instance(context);        make = TreeMaker.instance(context);        reader = ClassReader.instance(context);        todo = Todo.instance(context);        annotate = Annotate.instance(context);        types = Types.instance(context);        target = Target.instance(context);        skipAnnotations =            Options.instance(context).get("skipAnnotations") != null;    }    /** A queue for classes whose members still need to be entered into the     *  symbol table.     */    ListBuffer<Env<AttrContext>> halfcompleted = new ListBuffer<Env<AttrContext>>();    /** Set to true only when the first of a set of classes is     *  processed from the halfcompleted queue.     */    boolean isFirst = true;    /** A flag to disable completion from time to time during member     *  enter, as we only need to look up types.  This avoids     *  unnecessarily deep recursion.     */    boolean completionEnabled = true;    /* ---------- Processing import clauses ----------------     */    /** Import all classes of a class or package on demand.     *  @param pos           Position to be used for error reporting.     *  @param tsym          The class or package the members of which are imported.     *  @param toScope   The (import) scope in which imported classes     *               are entered.     */    private void importAll(int pos,                           final TypeSymbol tsym,                           Env<AttrContext> env) {        // Check that packages imported from exist (JLS ???).        if (tsym.kind == PCK && tsym.members().elems == null && !tsym.exists()) {            // If we can't find java.lang, exit immediately.            if (((PackageSymbol)tsym).fullname.equals(names.java_lang)) {                JCDiagnostic msg = JCDiagnostic.fragment("fatal.err.no.java.lang");                throw new FatalError(msg);            } else {                log.error(pos, "doesnt.exist", tsym);            }        }        final Scope fromScope = tsym.members();        final Scope toScope = env.toplevel.starImportScope;        for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {            if (e.sym.kind == TYP && !toScope.includes(e.sym))                toScope.enter(e.sym, fromScope);        }    }    /** Import all static members of a class or package on demand.     *  @param pos           Position to be used for error reporting.     *  @param tsym          The class or package the members of which are imported.     *  @param toScope   The (import) scope in which imported classes     *               are entered.     */    private void importStaticAll(int pos,                                 final TypeSymbol tsym,                                 Env<AttrContext> env) {        final JavaFileObject sourcefile = env.toplevel.sourcefile;        final Scope toScope = env.toplevel.starImportScope;        final PackageSymbol packge = env.toplevel.packge;        final TypeSymbol origin = tsym;        // enter imported types immediately        new Object() {            Set<Symbol> processed = new HashSet<Symbol>();            void importFrom(TypeSymbol tsym) {                if (tsym == null || !processed.add(tsym))                    return;                // also import inherited names                importFrom(types.supertype(tsym.type).tsym);                for (Type t : types.interfaces(tsym.type))                    importFrom(t.tsym);                final Scope fromScope = tsym.members();                for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {                    Symbol sym = e.sym;                    if (sym.kind == TYP &&                        (sym.flags() & STATIC) != 0 &&                        staticImportAccessible(sym, packge) &&                        sym.isMemberOf(origin, types) &&                        !toScope.includes(sym))                        toScope.enter(sym, fromScope, origin.members());                }            }        }.importFrom(tsym);        // enter non-types before annotations that might use them        annotate.earlier(new Annotate.Annotator() {            Set<Symbol> processed = new HashSet<Symbol>();            public String toString() {                return "import static " + tsym + ".*" + " in " + sourcefile;            }            void importFrom(TypeSymbol tsym) {                if (tsym == null || !processed.add(tsym))                    return;                // also import inherited names                importFrom(types.supertype(tsym.type).tsym);                for (Type t : types.interfaces(tsym.type))                    importFrom(t.tsym);                final Scope fromScope = tsym.members();                for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {                    Symbol sym = e.sym;                    if (sym.isStatic() && sym.kind != TYP &&                        staticImportAccessible(sym, packge) &&                        !toScope.includes(sym) &&                        sym.isMemberOf(origin, types)) {                        toScope.enter(sym, fromScope, origin.members());                    }                }            }            public void enterAnnotation() {                importFrom(tsym);            }        });    }    // is the sym accessible everywhere in packge?    boolean staticImportAccessible(Symbol sym, PackageSymbol packge) {        int flags = (int)(sym.flags() & AccessFlags);        switch (flags) {        default:        case PUBLIC:            return true;        case PRIVATE:            return false;        case 0:        case PROTECTED:            return sym.packge() == packge;        }    }    /** Import statics types of a given name.  Non-types are handled in Attr.     *  @param pos           Position to be used for error reporting.     *  @param tsym          The class from which the name is imported.     *  @param name          The (simple) name being imported.     *  @param env           The environment containing the named import     *                  scope to add to.     */    private void importNamedStatic(final DiagnosticPosition pos,                                   final TypeSymbol tsym,                                   final Name name,                                   final Env<AttrContext> env) {        if (tsym.kind != TYP) {            log.error(pos, "static.imp.only.classes.and.interfaces");            return;        }        final Scope toScope = env.toplevel.namedImportScope;        final PackageSymbol packge = env.toplevel.packge;        final TypeSymbol origin = tsym;        // enter imported types immediately        new Object() {            Set<Symbol> processed = new HashSet<Symbol>();            void importFrom(TypeSymbol tsym) {                if (tsym == null || !processed.add(tsym))                    return;                // also import inherited names                importFrom(types.supertype(tsym.type).tsym);                for (Type t : types.interfaces(tsym.type))                    importFrom(t.tsym);                for (Scope.Entry e = tsym.members().lookup(name);                     e.scope != null;                     e = e.next()) {                    Symbol sym = e.sym;                    if (sym.isStatic() &&                        sym.kind == TYP &&                        staticImportAccessible(sym, packge) &&                        sym.isMemberOf(origin, types) &&                        chk.checkUniqueStaticImport(pos, sym, toScope))                        toScope.enter(sym, sym.owner.members(), origin.members());                }            }        }.importFrom(tsym);        // enter non-types before annotations that might use them        annotate.earlier(new Annotate.Annotator() {            Set<Symbol> processed = new HashSet<Symbol>();            boolean found = false;            public String toString() {                return "import static " + tsym + "." + name;            }            void importFrom(TypeSymbol tsym) {                if (tsym == null || !processed.add(tsym))                    return;                // also import inherited names                importFrom(types.supertype(tsym.type).tsym);                for (Type t : types.interfaces(tsym.type))                    importFrom(t.tsym);                for (Scope.Entry e = tsym.members().lookup(name);                     e.scope != null;                     e = e.next()) {                    Symbol sym = e.sym;                    if (sym.isStatic() &&                        staticImportAccessible(sym, packge) &&                        sym.isMemberOf(origin, types)) {                        found = true;                        if (sym.kind == MTH ||                            sym.kind != TYP && chk.checkUniqueStaticImport(pos, sym, toScope))                            toScope.enter(sym, sym.owner.members(), origin.members());                    }                }            }            public void enterAnnotation() {                JavaFileObject prev = log.useSource(env.toplevel.sourcefile);                try {                    importFrom(tsym);                    if (!found) {                        log.error(pos, "cant.resolve.location",                                  JCDiagnostic.fragment("kindname.static"),                                  name, "", "", Resolve.typeKindName(tsym.type),                                  tsym.type);                    }                } finally {                    log.useSource(prev);                }            }        });    }    /** Import given class.     *  @param pos           Position to be used for error reporting.     *  @param tsym          The class to be imported.     *  @param env           The environment containing the named import     *                  scope to add to.     */    private void importNamed(DiagnosticPosition pos, Symbol tsym, Env<AttrContext> env) {        if (tsym.kind == TYP &&            chk.checkUniqueImport(pos, tsym, env.toplevel.namedImportScope))            env.toplevel.namedImportScope.enter(tsym, tsym.owner.members());    }    /** Construct method type from method signature.     *  @param typarams    The method's type parameters.     *  @param params      The method's value parameters.     *  @param res             The method's result type,     *                 null if it is a constructor.     *  @param thrown      The method's thrown exceptions.     *  @param env             The method's (local) environment.     */    Type signature(List<JCTypeParameter> typarams,                   List<JCVariableDecl> params,                   JCTree res,                   List<JCExpression> thrown,                   Env<AttrContext> env) {        // Enter and attribute type parameters.        List<Type> tvars = enter.classEnter(typarams, env);        attr.attribTypeVariables(typarams, env);        // Enter and attribute value parameters.        ListBuffer<Type> argbuf = new ListBuffer<Type>();        for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail) {            memberEnter(l.head, env);            argbuf.append(l.head.vartype.type);        }        // Attribute result type, if one is given.        Type restype = res == null ? syms.voidType : attr.attribType(res, env);        // Attribute thrown exceptions.

⌨️ 快捷键说明

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