📄 enter.java
字号:
* @param toScope The (import) scope in which imported classes
* are entered.
*/
private void importAll(int pos, TypeSymbol tsym, Env env) {
if (tsym.kind == PCK && tsym.members().elems == null && !tsym.exists()) {
if (((PackageSymbol) tsym).fullname.equals(names.java_lang)) {
String msg = Log.getLocalizedString("fatal.err.no.java.lang");
throw new FatalError(msg);
} else {
log.error(pos, "doesnt.exist", tsym.toJava());
}
}
Scope fromScope = tsym.members();
Scope toScope = env.toplevel.starImportScope;
for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling)
if (e.sym.kind == TYP && !isIncluded(e.sym, toScope))
toScope.enter(e.sym, fromScope);
}
/**
* Import given class.
* @param pos Position to be used for error reporting.
* @param tsym The class to be imported.
* @param toScope The (import) scope in which the imported class
* is entered.
*/
private void importNamed(int pos, Symbol tsym, Env env) {
if (tsym.kind == TYP && checkUniqueImport(pos, tsym, env)) {
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 typarams, List params, Tree res, List thrown, Env env) {
ListBuffer argbuf = new ListBuffer();
for (List l = params; l.nonEmpty(); l = l.tail)
argbuf.append(attr.attribType(((Tree.VarDef) l.head).vartype, env));
Type restype = res == null ? syms.voidType : attr.attribType(res, env);
ListBuffer thrownbuf = new ListBuffer();
for (List l = thrown; l.nonEmpty(); l = l.tail) {
Type exc = attr.attribType((Tree) l.head, env);
exc = chk.checkClassType(((Tree) l.head).pos, exc);
thrownbuf.append(exc);
}
Type mtype = new MethodType(argbuf.toList(), restype, thrownbuf.toList(),
syms.methodClass);
return mtype;
}
/**
* Visitor argument: the current environment
*/
protected Env env;
/**
* Visitor method: enter field and method definitions and process import
* clauses, catching any completion failure exceptions.
*/
protected void memberEnter(Tree tree, Env env) {
Env prevEnv = this.env;
try {
this.env = env;
tree.accept(this);
} catch (CompletionFailure ex) {
chk.completionError(tree.pos, ex);
}
finally { this.env = prevEnv;
} }
/**
* Visitor method: enter members in a list of trees.
*/
void memberEnter(List trees, Env env) {
for (List l = trees; l.nonEmpty(); l = l.tail)
memberEnter((Tree) l.head, env);
}
public void visitTopLevel(TopLevel tree) {
if (tree.starImportScope.elems != null) {
return;
}
if (checkClash && tree.pid != null) {
Symbol p = tree.packge;
while (p.owner != syms.rootPackage) {
p.owner.complete();
if (syms.classes.get(p.fullName()) != null) {
log.error(tree.pos, "pkg.clashes.with.class.of.same.name",
p.toJava());
}
p = p.owner;
}
}
importAll(tree.pos, reader.enterPackage(names.java_lang), env);
memberEnter(tree.defs, env);
}
public void visitImport(Import tree) {
Tree imp = tree.qualid;
Name name = TreeInfo.name(imp);
TypeSymbol p;
Env localEnv = env.dup(tree);
assert completionEnabled;
completionEnabled = false;
if (imp.tag == Tree.SELECT) {
Select s = (Select) imp;
p = attr.attribTree(s.selected, localEnv, TYP | PCK, Type.noType).tsym;
if (name == names.asterisk) {
chk.checkCanonical(s.selected);
importAll(tree.pos, p, env);
} else {
TypeSymbol c = attr.attribType(imp, localEnv).tsym;
chk.checkCanonical(imp);
importNamed(tree.pos, c, env);
}
} else {
assert false :
"malformed import clause";
}
completionEnabled = true;
}
public void visitMethodDef(MethodDef tree) {
Scope enclScope = enterScope(env);
MethodSymbol m = new MethodSymbol(0, tree.name, null, enclScope.owner);
m.flags_field = chk.checkFlags(tree.pos, tree.flags, m);
tree.sym = m;
Env localEnv = methodEnv(tree, env);
m.type = signature(tree.typarams, tree.params, tree.restype,
tree.thrown, localEnv);
((AttrContext) localEnv.info).scope.leave();
if (checkUnique(tree.pos, m, enclScope)) {
checkNotReserved(tree.pos, tree.name);
enclScope.enter(m);
}
}
public void visitVarDef(VarDef tree) {
Env localEnv = env;
if ((tree.flags & STATIC) != 0) {
localEnv = env.dup(tree, ((AttrContext) env.info).dup());
((AttrContext) localEnv.info).staticLevel++;
}
attr.attribType(tree.vartype, localEnv);
Scope enclScope = enterScope(env);
VarSymbol v =
new VarSymbol(0, tree.name, tree.vartype.type, enclScope.owner);
v.flags_field = chk.checkFlags(tree.pos, tree.flags, v);
tree.sym = v;
if (tree.init != null) {
v.flags_field |= HASINIT;
if ((v.flags_field & FINAL) != 0)
v.constValue = initEnv(tree, env);
}
if (checkUnique(tree.pos, v, enclScope)) {
checkNotReserved(tree.pos, tree.name);
checkTransparentVar(tree.pos, v, enclScope);
enclScope.enter(v);
}
v.pos = tree.pos;
}
/**
* Default member enter visitor method: do nothing
*/
public void visitTree(Tree tree) {
}
}
/**
* A completer class for source classes
*/
class CompleteEnter implements Completer {
CompleteEnter() {
super();
}
/**
* Complete entering a class.
* @param sym The symbol of the class to be completed.
*/
public void complete(Symbol sym) throws CompletionFailure {
if (!completionEnabled) {
sym.completer = this;
return;
}
ClassSymbol c = (ClassSymbol) sym;
ClassType ct = (ClassType) c.type;
Env env = (Env) classEnvs.get(c);
ClassDef tree = (ClassDef) env.tree;
Name prev = log.useSource(env.toplevel.sourcefile);
boolean isFirst = halfcompleted.isEmpty();
try {
halfcompleted.append(env);
if (c.owner.kind == PCK) {
phase2.memberEnter(env.toplevel, env.enclosing(Tree.TOPLEVEL));
todo.append(env);
}
try {
c.flags_field |= (LOCKED | UNATTRIBUTED);
if (c.owner.kind == TYP) {
c.owner = chk.checkNonCyclic(tree.pos, c.owner.type).tsym;
c.owner.complete();
}
Type supertype = (tree.extending != null) ?
attribBase(tree.extending, env, true, false) :
(c.fullname == names.java_lang_Object) ?
Type.noType : syms.objectType;
ListBuffer interfaces = new ListBuffer();
Set interfaceSet = Set.make();
for (List l = tree.implementing; l.nonEmpty(); l = l.tail) {
Type i = attribBase((Tree) l.head, env, false, true);
if (i.tag == CLASS) {
interfaces.append(i);
chk.checkNotRepeated(((Tree) l.head).pos, i,
interfaceSet);
}
}
ct.supertype_field = supertype;
ct.interfaces_field = interfaces.toList();
if (c.fullname == names.java_lang_Object) {
if (tree.extending != null) {
chk.checkNonCyclic(tree.extending.pos, supertype);
ct.supertype_field = Type.noType;
} else if (tree.implementing.nonEmpty()) {
chk.checkNonCyclic( ((Tree) tree.implementing.head).pos,
(Type) ct.interfaces_field.head);
ct.interfaces_field = Type.emptyList;
}
}
}
finally { c.flags_field &= ~LOCKED;
} attr.attribStats(tree.typarams, env);
if ((c.flags() & INTERFACE) == 0 &&
!TreeInfo.hasConstructors(tree.defs)) {
List argtypes = Type.emptyList;
List thrown = Type.emptyList;
boolean based = false;
if (c.name.len == 0) {
NewClass nc = (NewClass) env.next.tree;
if (nc.constructor != null) {
Type superConstrType = c.type.memberType(nc.constructor);
argtypes = superConstrType.argtypes();
if (nc.encl != null) {
argtypes = argtypes.prepend(nc.encl.type);
based = true;
}
thrown = superConstrType.thrown();
}
}
Tree constrDef =
DefaultConstructor(make.at(tree.pos), c, argtypes,
thrown, based);
tree.defs = tree.defs.prepend(constrDef);
}
if ((c.flags_field & INTERFACE) == 0) {
VarSymbol thisSym =
new VarSymbol(FINAL | HASINIT, names._this, c.type, c);
thisSym.pos = Position.FIRSTPOS;
((AttrContext) env.info).scope.enter(thisSym);
if (ct.supertype_field.tag == CLASS) {
VarSymbol superSym =
new VarSymbol(FINAL | HASINIT, names._super,
ct.supertype_field, c);
superSym.pos = Position.FIRSTPOS;
((AttrContext) env.info).scope.enter(superSym);
}
}
} catch (CompletionFailure ex) {
chk.completionError(tree.pos, ex);
}
if (checkClash && c.owner.kind == PCK && c.owner != syms.emptyPackage &&
reader.packageExists(c.fullname)) {
log.error(tree.pos, "clash.with.pkg.of.same.name", c.toJava());
}
log.useSource(prev);
if (isFirst) {
while (halfcompleted.nonEmpty()) {
finish((Env) halfcompleted.next());
}
}
}
/**
* Enter member fields and methods of a class
* @param env the environment current for the class block.
*/
private void finish(Env env) {
Name prev = log.useSource(env.toplevel.sourcefile);
ClassDef tree = (ClassDef) env.tree;
ClassSymbol c = tree.sym;
phase2.memberEnter(tree.defs, env);
log.useSource(prev);
}
/**
* Attribute extended or implemented type reference, and check
* for cyclic references.
* @param tree The tree expressing the type reference.At
* @param env The environment current at the type reference.
* @param classExpected true if only a class is expected here.
* @param interfaceExpected true if only an interface is expected here.
*/
private Type attribBase(Tree tree, Env env, boolean classExpected,
boolean interfaceExpected) {
Type t = attr.attribBase(tree, env, classExpected, interfaceExpected);
return chk.checkNonCyclic(tree.pos, t);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -