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

📄 enter.java

📁 java编译器gjc源码 java编译环境
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
    /**
      * 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.
          *  @param pos	     Position to be used for error reporting.
          *  @param tsym	     The class or package the members of which are imported.

⌨️ 快捷键说明

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