⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enter.java

📁 java编译器gjc源码 java编译环境
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/**
 * @(#)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;
    }

⌨️ 快捷键说明

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