?? enter.java
字號:
/** * @(#)Enter.java 1.83 03/01/23 * * 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 java.io.File;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.*;/** * This class enters symbols for all encountered definitions into * the symbol table. The pass consists of two phases, organized as * follows: * * In the first phase, all class symbols are intered into their enclosing scope, * descending recursively down the tree for classes which are members of other * classes. The class symbols are given a CompleteEnter object as completer. * * In the second phase classes are completed using CompleteEnter.complete(). * Completion might occur on demand, but any classes that are not completed that * way will be eventually completed by processing the `uncompleted' queue. * Completion entails (1) determination of a classe's parameters, supertype and * interfaces, as well as (2) entering all symbols defined in the class into its * scope, with the exception of class symbols which have been entered in phase 1. * (2) depends on (1) having been completed for a class and all its superclasses * and enclosing classes. That's why, after doing (1), we put classes in a * `halfcompleted' queue. Only when we have performed (1) for a class and all it's * superclasses and enclosing classes, we proceed to (2). * * Whereas the first phase is organized as a sweep through all compiled * syntax trees, the second phase is demand. Members of a class are entered * when the contents of a class are first accessed. This is accomplished * by installing completer objects in class symbols for compiled classes * which invoke the member-enter phase for the corresponding class tree. * * Classes migrate from one phase to the next via queues: * * class enter -> (uncompleted) --> member enter (1) * -> (halfcompleted) --> member enter (2) * -> (todo) --> attribute // only for toplevel classes */public class Enter extends Tree.Visitor implements Flags, Kinds, TypeTags { private static final Context.Key enterKey = new Context.Key(); private Log log; private Symtab syms; private Resolve rs; private Check chk; private TreeMaker make; private Attr attr; private ClassReader reader; private Name.Table names; protected MemberEnter phase2; /** * A queue of all as yet unattributed toplevel classes */ Todo todo; public static Enter instance(Context context) { Enter instance = (Enter) context.get(enterKey); if (instance == null) instance = new Enter(context); return instance; } protected Enter(Context context) { super(); context.put(enterKey, this); names = Name.Table.instance(context); log = Log.instance(context); reader = ClassReader.instance(context); make = TreeMaker.instance(context); todo = Todo.instance(context); syms = Symtab.instance(context); rs = Resolve.instance(context); chk = Check.instance(context); attr = Attr.instance(context); phase2 = new MemberEnter(); predefClassDef = new ClassDef(PUBLIC, syms.predefClass.name, null, null, null, null, syms.predefClass); } /** * A switch to determine whether we check for package/class conflicts */ static final boolean checkClash = true; /** * A hashtable mapping classes to the environments current at the point * of the class declaration's local definitions. */ Hashtable classEnvs = Hashtable.make(); /** * Accessor for classEnvs */ public Env getEnv(ClassSymbol c) { return (Env) classEnvs.get(c); } /** * The queue of all classes that might still need to be completed; * saved and initialized by main(). */ ListBuffer uncompleted; /** * A queue for classes whose members still need to be entered into the * symbol table. */ ListBuffer halfcompleted = new ListBuffer(); /** * A dummy class to serve as enclClass for toplevel environments. */ private ClassDef predefClassDef; /** * A flag to enable/disable class completion. This is * necessary to prevent false cyclic dependencies involving imports. * Example (due to Todd Turnbridge): Consider the following three files: * * A.java: public class A extends B {} * B.java: public class B extends C {} * C.java: import A; public class C {} * * Now compile B.java. The (import A;) is not allowed to go beyond enter * phase, or a false cycle will occur. */ private boolean completionEnabled = true; /** * Generate call to superclass constructor. This is: * * super(id_0, ..., id_n) * * or, if based == true * * id_0.super(id_1,...,id_n) * * where id_0, ..., id_n are the names of the given parameters. * * @param make The tree factory * @param params The parameters that need to be passed to super * @param based Is first parameter a this$n? */ Tree SuperCall(TreeMaker make, List params, boolean based) { Tree meth; if (based) { meth = make.Select(make.Ident((Tree.VarDef) params.head), names._super); params = params.tail; } else { meth = make.Ident(names._super); } return make.Exec(make.Apply(meth, make.Idents(params))); } /** * Generate default constructor for given class. For classes different * from java.lang.Object, this is: * * c(argtype_0 x_0, ..., argtype_n x_n) throws thrown { * super(x_0, ..., x_n) * } * * or, if based == true: * * c(argtype_0 x_0, ..., argtype_n x_n) throws thrown { * x_0.super(x_1, ..., x_n) * } * * @param make The tree factory. * @param c The class owning the default constructor. * @param argtypes The parameter types of the constructor. * @param thrown The thrown exceptions of the constructor. * @param based Is first parameter a this$n? */ Tree DefaultConstructor(TreeMaker make, ClassSymbol c, List argtypes, List thrown, boolean based) { List params = make.Params(argtypes, syms.noSymbol); List stats = Tree.emptyList; if (c.type != syms.objectType) stats = stats.prepend(SuperCall(make, params, based)); long flags = c.flags() & Check.AccessFlags; if (c.name.len == 0) flags |= ANONCONSTR; Tree result = make.MethodDef(flags, names.init, null, TypeParameter.emptyList, params, make.Types(thrown), make.Block(0, stats)); return result; } /** * Report duplicate declaration error. */ private void duplicateError(int pos, Symbol sym) { if (!sym.type.isErroneous()) { log.error(pos, "already.defined", sym.toJava(), sym.javaLocation()); } } /** * Check that symbol is unique in given scope. * @param pos Position for error reporting. * @param sym The symbol. * @param s The scope. */ private boolean checkUnique(int pos, Symbol sym, Scope s) { if (sym.owner.name == names.any) return false; for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) { if (sym != e.sym && sym.kind == e.sym.kind && sym.name != names.error && (sym.kind != MTH || sym.type.hasSameArgs(e.sym.type))) { duplicateError(pos, e.sym); return false; } } return true; } /** * Check that single-type import is not already imported or top-level defined, * but make an exception for two single-type imports which denote the same type. * @param pos Position for error reporting. * @param sym The symbol. * @param env The current environment. */ private boolean checkUniqueImport(int pos, Symbol sym, Env env) { Scope s = env.toplevel.namedImportScope; for (Scope.Entry e = s.lookup(sym.name); e.scope != null; e = e.next()) { boolean isClassDecl = e.scope == s; if ((isClassDecl || sym != e.sym) && sym.kind == e.sym.kind && sym.name != names.error) { if (!e.sym.type.isErroneous()) { String what = e.sym.toJava(); if (!isClassDecl) log.error(pos, "already.defined.single.import", what); else if (sym != e.sym) log.error(pos, "already.defined.this.unit", what); } return false; } } return true; } /** * Check that variable does not hide variable with same name in * immediately enclosing local scope. * @param pos Position for error reporting. * @param sym The symbol. * @param s The scope. */ private void checkTransparentVar(int pos, VarSymbol v, Scope s) { if (s.next != null) { for (Scope.Entry e = s.next.lookup(v.name); e.scope != null && e.sym.owner == v.owner; e = e.next()) { if (e.sym.kind == VAR && (e.sym.owner.kind & (VAR | MTH)) != 0 && v.name != names.error) { duplicateError(pos, e.sym); return; } } } } /** * Check that a class or interface does not hide a class or * interface with same name in immediately enclosing local scope. * @param pos Position for error reporting. * @param sym The symbol. * @param s The scope. */ private void checkTransparentClass(int pos, ClassSymbol c, Scope s) { if (s.next != null) { for (Scope.Entry e = s.next.lookup(c.name); e.scope != null && e.sym.owner == c.owner; e = e.next()) { if (e.sym.kind == TYP && (e.sym.owner.kind & (VAR | MTH)) != 0 && c.name != names.error) { duplicateError(pos, e.sym); return; } } } } /** * Check that class does not have the same name as one of * its enclosing classes, or as a class defined in its enclosing scope. * return true if class is unique in its enclosing scope. * @param pos Position for error reporting. * @param name The class name. * @param s The enclosing scope. */ private boolean checkUniqueClassName(int pos, Name name, Scope s) { for (Scope.Entry e = s.lookup(name); e.scope == s; e = e.next()) { if (e.sym.kind == TYP && e.sym.name != names.error) { duplicateError(pos, e.sym); return false; } } for (Symbol sym = s.owner; sym != null; sym = sym.owner) { if (sym.kind == TYP && sym.name == name && sym.name != names.error) { duplicateError(pos, sym); return true; } } return true; }
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -