enter.java

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

JAVA
490
字号
    Type classEnter(JCTree tree, Env<AttrContext> env) {	Env<AttrContext> 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.     */    <T extends JCTree> List<Type> classEnter(List<T> trees, Env<AttrContext> env) {	ListBuffer<Type> ts = new ListBuffer<Type>();	for (List<T> l = trees; l.nonEmpty(); l = l.tail)	    ts.append(classEnter(l.head, env));	return ts.toList();    }    public void visitTopLevel(JCCompilationUnit tree) {	JavaFileObject prev = log.useSource(tree.sourcefile);        boolean addEnv = false;	boolean isPkgInfo = tree.sourcefile.isNameCompatible("package-info",							     JavaFileObject.Kind.SOURCE);	if (tree.pid != null) {	    tree.packge = reader.enterPackage(TreeInfo.fullName(tree.pid));	    if (tree.packageAnnotations.nonEmpty()) {                if (isPkgInfo) {                    addEnv = true;                } else {                    log.error(tree.packageAnnotations.head.pos(),                              "pkg.annotations.sb.in.package-info.java");                }	    }	} else {	    tree.packge = syms.unnamedPackage;	}	tree.packge.complete(); // Find all classes in package.        Env<AttrContext> env = topLevelEnv(tree);	// Save environment of package-info.java file.	if (isPkgInfo) {	    Env<AttrContext> env0 = typeEnvs.get(tree.packge);	    if (env0 == null) {		typeEnvs.put(tree.packge, env);	    } else {		JCCompilationUnit tree0 = env0.toplevel;                if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) {		    log.warning(tree.pid != null ? tree.pid.pos()						 : null,				"pkg-info.already.seen",				tree.packge);		    if (addEnv || (tree0.packageAnnotations.isEmpty() &&				   tree.docComments != null &&				   tree.docComments.get(tree) != null)) {			typeEnvs.put(tree.packge, env);		    }		}	    }	}	classEnter(tree.defs, env);        if (addEnv) {            todo.append(env);        }	log.useSource(prev);	result = null;    }    public void visitClassDef(JCClassDecl tree) {	Symbol owner = env.info.scope.owner;	Scope enclScope = enterScope(env);	ClassSymbol c;	if (owner.kind == PCK) {	    // We are seeing a toplevel class.	    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.mods.flags & PUBLIC) != 0 && !classNameMatchesFileName(c, env)) {		log.error(tree.pos(),			  "class.public.should.be.in.file", tree.name);	    }	} else {	    if (tree.name.len != 0 &&		!chk.checkUniqueClassName(tree.pos(), tree.name, enclScope)) {		result = null;		return;	    }	    if (owner.kind == TYP) {		// We are seeing a member class.		c = reader.enterClass(tree.name, (TypeSymbol)owner);		if ((owner.flags_field & INTERFACE) != 0) {		    tree.mods.flags |= PUBLIC | STATIC;		}	    } else {		// We are seeing a local class.		c = reader.defineClass(tree.name, owner);		c.flatname = chk.localClassName(c);		if (c.name.len != 0)		    chk.checkTransparentClass(tree.pos(), c, env.info.scope);	    }	}	tree.sym = c;	// Enter class into `compiled' table and enclosing scope.	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);	// Set up an environment for class block and store in `typeEnvs'	// table, to be retrieved later in memberEnter and attribution.	Env<AttrContext> localEnv = classEnv(tree, env);	typeEnvs.put(c, localEnv);	// Fill out class fields.	c.completer = memberEnter;	c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree);	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) {	    // We are seeing a local or inner class.	    // Set outer_field of this class to closest enclosing class	    // which contains this class in a non-static context	    // (its "enclosing instance class"), provided such a class exists.	    Symbol owner1 = owner;	    while ((owner1.kind & (VAR | MTH)) != 0 &&		   (owner1.flags_field & STATIC) == 0) {		owner1 = owner1.owner;	    }	    if (owner1.kind == TYP) {		ct.setEnclosingType(owner1.type);	    }	}	// Enter type parameters.	ct.typarams_field = classEnter(tree.typarams, localEnv);	// Add non-local class to uncompleted, to make sure it will be	// completed later.	if (!c.isLocal() && uncompleted != null) uncompleted.append(c);//	System.err.println("entering " + c.fullname + " in " + c.owner);//DEBUG	// Recursively enter all member classes.	classEnter(tree.defs, localEnv);	result = c.type;    }    //where	/** Does class have the same name as the file it appears in?	 */	private static boolean classNameMatchesFileName(ClassSymbol c,							Env<AttrContext> env) {	    return env.toplevel.sourcefile.isNameCompatible(c.name.toString(),							    JavaFileObject.Kind.SOURCE);	}    /** Complain about a duplicate class. */    protected void duplicateClass(DiagnosticPosition pos, ClassSymbol c) {	log.error(pos, "duplicate.class", c.fullname);    }    /** Class enter visitor method for type parameters.     *	Enter a symbol for type parameter in local scope, after checking that it     *	is unique.     */    public void visitTypeParameter(JCTypeParameter tree) {	TypeVar a = (tree.type != null)	    ? (TypeVar)tree.type	    : new TypeVar(tree.name, env.info.scope.owner, syms.botType);	tree.type = a;	if (chk.checkUnique(tree.pos(), a.tsym, env.info.scope)) {	    env.info.scope.enter(a.tsym);	}	result = a;    }    /** Default class enter visitor method: do nothing.     */    public void visitTree(JCTree 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<JCCompilationUnit> 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<JCCompilationUnit> trees, ClassSymbol c) {        annotate.enterStart();	ListBuffer<ClassSymbol> prevUncompleted = uncompleted;	if (memberEnter.completionEnabled) uncompleted = new ListBuffer<ClassSymbol>();	try {	    // enter all classes, and construct uncompleted list	    classEnter(trees, null);	    // complete all uncompleted classes in memberEnter	    if  (memberEnter.completionEnabled) {		while (uncompleted.nonEmpty()) {		    ClassSymbol clazz = uncompleted.next();		    if (c == null || c == clazz || prevUncompleted == null)			clazz.complete();		    else			// defer			prevUncompleted.append(clazz);		}		// if there remain any unimported toplevels (these must have		// no classes at all), process their import statements as well.		for (JCCompilationUnit tree : trees) {		    if (tree.starImportScope.elems == null) {			JavaFileObject prev = log.useSource(tree.sourcefile);			Env<AttrContext> env = typeEnvs.get(tree);			if (env == null)			    env = topLevelEnv(tree);			memberEnter.memberEnter(tree, env);			log.useSource(prev);		    }		}	    }	} finally {	    uncompleted = prevUncompleted;            annotate.enterDone();	}    }}

⌨️ 快捷键说明

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