📄 enter.java
字号:
/** * Check that name does not clash with internal names used in the * translation process. */ private void checkNotReserved(int pos, Name name) { if (name == names.classDollar || name.startsWith(names.thisDollar)) { log.error(pos, "name.reserved.for.internal.use", name.toJava()); } } /** * Create a fresh environment for method bodies. * @param tree The method definition. * @param env The environment current outside of the method definition. */ Env methodEnv(MethodDef tree, Env env) { Env localEnv = env.dup(tree, ((AttrContext) env.info).dup( ((AttrContext) env.info).scope.dupUnshared())); localEnv.enclMethod = tree; ((AttrContext) localEnv.info).scope.owner = tree.sym; if ((tree.flags & STATIC) != 0) ((AttrContext) localEnv.info).staticLevel++; return localEnv; } /** * Create a fresh environment for class bodies. * This will create a fresh scope for local symbols of a class, referred * to by the environments info.scope field. * This scope will contain * - symbols for this and super * - symbols for any type parameters * In addition, it serves as an anchor for scopes of methods and initializers * which are nested in this scope via Scope.dup(). * This scope should not be confused with the members scope of a class. * * @param tree The class definition. * @param env The environment current outside of the class definition. */ public Env classEnv(ClassDef tree, Env env) { Env localEnv = env.dup(tree, ((AttrContext) env.info).dup(new Scope(tree.sym))); localEnv.enclClass = tree; localEnv.outer = env; ((AttrContext) localEnv.info).isSelfCall = false; return localEnv; } /** * Create a fresh environment for toplevels. * @param tree The toplevel tree. */ Env topLevelEnv(TopLevel tree) { Env localEnv = new Env(tree, new AttrContext()); localEnv.toplevel = tree; localEnv.enclClass = predefClassDef; tree.namedImportScope = new Scope(tree.packge); tree.starImportScope = new Scope(tree.packge); ((AttrContext) localEnv.info).scope = tree.namedImportScope; return localEnv; } /** * Create a fresh environment for a variable's initializer. * If the variable is a field, the owner of the environment's scope * is be the variable itself, otherwise the owner is the method * enclosing the variable definition. * * @param tree The variable definition. * @param env The environment current outside of the variable definition. */ Env initEnv(VarDef tree, Env env) { Env localEnv = env.dupto(new AttrContextEnv(tree, ((AttrContext) env.info).dup())); if (tree.sym.owner.kind == TYP) { ((AttrContext) localEnv.info).scope = ((AttrContext) env.info).scope.dup(); ((AttrContext) localEnv.info).scope.owner = tree.sym; } if ((tree.flags & STATIC) != 0 || (env.enclClass.sym.flags() & INTERFACE) != 0) ((AttrContext) localEnv.info).staticLevel++; return localEnv; } /** * The scope in which a member definition in environment env is to be entered * This is usually the environment's scope, except for class environments, * where the local scope is for type variables, and the this and super symbol * only, and members go into the class member scope. */ Scope enterScope(Env env) { return (env.tree.tag == Tree.CLASSDEF) ? ((ClassDef) env.tree).sym.members_field : ((AttrContext) env.info).scope; } /** * Visitor argument: the current environment. */ protected Env env; /** * Visitor result: the computed type. */ Type result; /** * Visitor method: enter all classes in given tree, catching any * completion failure exceptions. Return the tree's type. * * @param tree The tree to be visited. * @param env The environment visitor argument. */ Type classEnter(Tree tree, Env env) { Env prevEnv = this.env; try { this.env = env; tree.accept(this); return result; } catch (CompletionFailure ex) { return chk.completionError(tree.pos, ex); } finally { this.env = prevEnv; } } /** * Visitor method: enter classes of a list of trees, returning a list of types. */ List classEnter(List trees, Env env) { ListBuffer ts = new ListBuffer(); for (List l = trees; l.nonEmpty(); l = l.tail) ts.append(classEnter((Tree) l.head, env)); return ts.toList(); } public void visitTopLevel(TopLevel tree) { Name prev = log.useSource(tree.sourcefile); if (tree.pid != null) { tree.packge = reader.enterPackage(TreeInfo.fullName(tree.pid)); } else { tree.packge = syms.emptyPackage; } tree.packge.complete(); classEnter(tree.defs, topLevelEnv(tree)); log.useSource(prev); result = null; } public void visitClassDef(ClassDef tree) { Symbol owner = ((AttrContext) env.info).scope.owner; Scope enclScope = enterScope(env); ClassSymbol c; if (owner.kind == PCK) { PackageSymbol packge = (PackageSymbol) owner; for (Symbol q = packge; q != null && q.kind == PCK; q = q.owner) q.flags_field |= EXISTS; c = reader.enterClass(tree.name, packge); packge.members().enterIfAbsent(c); if ((tree.flags & PUBLIC) != 0 && !classNameMatchesFileName(c, env)) { log.error(tree.pos, "class.public.should.be.in.file", tree.name.toJava()); } } else { if (tree.name.len != 0 && !checkUniqueClassName(tree.pos, tree.name, enclScope)) { result = null; return; } if (owner.kind == TYP) { c = reader.enterClass(tree.name, (TypeSymbol) owner); if ((owner.flags_field & INTERFACE) != 0) { tree.flags |= PUBLIC | STATIC; } } else { c = reader.defineClass(tree.name, owner); c.flatname = chk.localClassName(c); if (c.name.len != 0) checkTransparentClass(tree.pos, c, ((AttrContext) env.info).scope); } } tree.sym = c; if (chk.compiled.get(c.flatname) != null) { duplicateClass(tree.pos, c); result = new ErrorType(tree.name, (TypeSymbol) owner); tree.sym = (ClassSymbol) result.tsym; return; } chk.compiled.put(c.flatname, c); enclScope.enter(c); Env localEnv = classEnv(tree, env); classEnvs.put(c, localEnv); c.completer = new CompleteEnter(); c.flags_field = chk.checkFlags(tree.pos, tree.flags, c); c.sourcefile = env.toplevel.sourcefile; c.members_field = new Scope(c); ClassType ct = (ClassType) c.type; if (owner.kind != PCK && (c.flags_field & STATIC) == 0) { Symbol owner1 = owner; while ((owner1.kind & (VAR | MTH)) != 0 && (owner1.flags_field & STATIC) == 0) { owner1 = owner1.owner; } if (owner1.kind == TYP) { ct.outer_field = owner1.type; } } ct.typarams_field = classEnter(tree.typarams, localEnv); if (!c.isLocal() && uncompleted != null) uncompleted.append(c); classEnter(tree.defs, localEnv); result = c.type; } /** * Does class have the same name as the file it appears in? */ private static boolean classNameMatchesFileName(ClassSymbol c, Env env) { String fname = env.toplevel.sourcefile.toString(); String cname = c.name + ".java"; try { return endsWith(fname, cname) || endsWith(new File(fname).getCanonicalPath(), cname); } catch (java.io.IOException ex) { return false; } } /** * Does path name have file name as last component? */ private static boolean endsWith(String pathname, String filename) { return pathname.endsWith(filename) && (pathname.length() == filename.length() || pathname.charAt(pathname.length() - filename.length() - 1) == File.separatorChar); } /** * Complain about a duplicate class. */ protected void duplicateClass(int pos, ClassSymbol c) { log.error(pos, "duplicate.class", c.fullname.toJava()); } /** * Default class enter visitor method: do nothing. */ public void visitTree(Tree tree) { result = null; } /** * Main method: enter all classes in a list of toplevel trees. * @param trees The list of trees to be processed. */ public void main(List trees) { complete(trees, null); } /** * Main method: enter one class from a list of toplevel trees and * place the rest on uncompleted for later processing. * @param trees The list of trees to be processed. * @param c The class symbol to be processed. */ public void complete(List trees, ClassSymbol c) { ListBuffer prevUncompleted = uncompleted; if (completionEnabled) uncompleted = new ListBuffer(); try { classEnter(trees, null); if (completionEnabled) { while (uncompleted.nonEmpty()) { ClassSymbol clazz = (Symbol.ClassSymbol) uncompleted.next(); if (c == null || c == clazz || prevUncompleted == null) clazz.complete(); else prevUncompleted.append(clazz); } for (List l = trees; l.nonEmpty(); l = l.tail) { TopLevel tree = (TopLevel) l.head; if (tree.starImportScope.elems == null) { Name prev = log.useSource(tree.sourcefile); phase2.memberEnter(tree, topLevelEnv(tree)); log.useSource(prev); } } } } finally { uncompleted = prevUncompleted; } } /** * Enter all members of a class. This is done in a second phase * after the classes themselves have been entered. */ protected class MemberEnter extends Tree.Visitor { protected MemberEnter() { super(); } /** * Given a class, and an (import) scope, is there already a * class with same fully qualified name in this scope? */ private boolean isIncluded(Symbol c, Scope scope) { for (Scope.Entry e = scope.lookup(c.name); e.scope == scope; e = e.next()) { if (e.sym.kind == c.kind && e.sym.fullName() == c.fullName()) return true; } return false; } /** * Import all classes of a class or package on demand.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -