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 + -
显示快捷键?