memberenter.java

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

JAVA
1,108
字号
        ListBuffer<Type> thrownbuf = new ListBuffer<Type>();        for (List<JCExpression> l = thrown; l.nonEmpty(); l = l.tail) {            Type exc = attr.attribType(l.head, env);            if (exc.tag != TYPEVAR)                exc = chk.checkClassType(l.head.pos(), exc);            thrownbuf.append(exc);        }        Type mtype = new MethodType(argbuf.toList(),                                    restype,                                    thrownbuf.toList(),                                    syms.methodClass);        return tvars.isEmpty() ? mtype : new ForAll(tvars, mtype);    }/* ******************************************************************** * Visitor methods for member enter *********************************************************************/    /** Visitor argument: the current environment     */    protected Env<AttrContext> env;    /** Enter field and method definitions and process import     *  clauses, catching any completion failure exceptions.     */    protected void memberEnter(JCTree tree, Env<AttrContext> env) {        Env<AttrContext> prevEnv = this.env;        try {            this.env = env;            tree.accept(this);        }  catch (CompletionFailure ex) {            chk.completionError(tree.pos(), ex);        } finally {            this.env = prevEnv;        }    }    /** Enter members from a list of trees.     */    void memberEnter(List<? extends JCTree> trees, Env<AttrContext> env) {        for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail)            memberEnter(l.head, env);    }    /** Enter members for a class.     */    void finishClass(JCClassDecl tree, Env<AttrContext> env) {        if ((tree.mods.flags & Flags.ENUM) != 0 &&            (types.supertype(tree.sym.type).tsym.flags() & Flags.ENUM) == 0) {            addEnumMembers(tree, env);        }        memberEnter(tree.defs, env);    }    /** Add the implicit members for an enum type     *  to the symbol table.     */    private void addEnumMembers(JCClassDecl tree, Env<AttrContext> env) {        JCExpression valuesType = make.Type(new ArrayType(tree.sym.type, syms.arrayClass));        // public static T[] values() { return ???; }        JCMethodDecl values = make.            MethodDef(make.Modifiers(Flags.PUBLIC|Flags.STATIC),                      names.values,                      valuesType,                      List.<JCTypeParameter>nil(),                      List.<JCVariableDecl>nil(),                      List.<JCExpression>nil(), // thrown                      null, //make.Block(0, Tree.emptyList.prepend(make.Return(make.Ident(names._null)))),                      null);        memberEnter(values, env);        // public static T valueOf(String name) { return ???; }        JCMethodDecl valueOf = make.            MethodDef(make.Modifiers(Flags.PUBLIC|Flags.STATIC),                      names.valueOf,                      make.Type(tree.sym.type),                      List.<JCTypeParameter>nil(),                      List.of(make.VarDef(make.Modifiers(Flags.PARAMETER),                                            names.fromString("name"),                                            make.Type(syms.stringType), null)),                      List.<JCExpression>nil(), // thrown                      null, //make.Block(0, Tree.emptyList.prepend(make.Return(make.Ident(names._null)))),                      null);        memberEnter(valueOf, env);        // the remaining members are for bootstrapping only        if (!target.compilerBootstrap(tree.sym)) return;        // public final int ordinal() { return ???; }        JCMethodDecl ordinal = make.at(tree.pos).            MethodDef(make.Modifiers(Flags.PUBLIC|Flags.FINAL),                      names.ordinal,                      make.Type(syms.intType),                      List.<JCTypeParameter>nil(),                      List.<JCVariableDecl>nil(),                      List.<JCExpression>nil(),                      null,                      null);        memberEnter(ordinal, env);        // public final String name() { return ???; }        JCMethodDecl name = make.            MethodDef(make.Modifiers(Flags.PUBLIC|Flags.FINAL),                      names._name,                      make.Type(syms.stringType),                      List.<JCTypeParameter>nil(),                      List.<JCVariableDecl>nil(),                      List.<JCExpression>nil(),                      null,                      null);        memberEnter(name, env);        // public int compareTo(E other) { return ???; }        MethodSymbol compareTo = new            MethodSymbol(Flags.PUBLIC,                         names.compareTo,                         new MethodType(List.of(tree.sym.type),                                        syms.intType,                                        List.<Type>nil(),                                        syms.methodClass),                         tree.sym);        memberEnter(make.MethodDef(compareTo, null), env);    }    public void visitTopLevel(JCCompilationUnit tree) {        if (tree.starImportScope.elems != null) {            // we must have already processed this toplevel            return;        }        // check that no class exists with same fully qualified name as        // toplevel package        if (checkClash && tree.pid != null) {            Symbol p = tree.packge;            while (p.owner != syms.rootPackage) {                p.owner.complete(); // enter all class members of p                if (syms.classes.get(p.getQualifiedName()) != null) {                    log.error(tree.pos,                              "pkg.clashes.with.class.of.same.name",                              p);                }                p = p.owner;            }        }        // process package annotations        annotateLater(tree.packageAnnotations, env, tree.packge);        // Import-on-demand java.lang.        importAll(tree.pos, reader.enterPackage(names.java_lang), env);        // Process all import clauses.        memberEnter(tree.defs, env);    }    // process the non-static imports and the static imports of types.    public void visitImport(JCImport tree) {        JCTree imp = tree.qualid;        Name name = TreeInfo.name(imp);        TypeSymbol p;        // Create a local environment pointing to this tree to disable        // effects of other imports in Resolve.findGlobalType        Env<AttrContext> localEnv = env.dup(tree);        // Attribute qualifying package or class.        JCFieldAccess s = (JCFieldAccess) imp;        p = attr.            attribTree(s.selected,                       localEnv,                       tree.staticImport ? TYP : (TYP | PCK),                       Type.noType).tsym;        if (name == names.asterisk) {            // Import on demand.            chk.checkCanonical(s.selected);            if (tree.staticImport)                importStaticAll(tree.pos, p, env);            else                importAll(tree.pos, p, env);        } else {            // Named type import.            if (tree.staticImport) {                importNamedStatic(tree.pos(), p, name, localEnv);                chk.checkCanonical(s.selected);            } else {                TypeSymbol c = attribImportType(imp, localEnv).tsym;                chk.checkCanonical(imp);                importNamed(tree.pos(), c, env);            }        }    }    public void visitMethodDef(JCMethodDecl tree) {        Scope enclScope = enter.enterScope(env);        MethodSymbol m = new MethodSymbol(0, tree.name, null, enclScope.owner);        m.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, m, tree);        tree.sym = m;        Env<AttrContext> localEnv = methodEnv(tree, env);        // Compute the method type        m.type = signature(tree.typarams, tree.params,                           tree.restype, tree.thrown,                           localEnv);        // Set m.params        ListBuffer<VarSymbol> params = new ListBuffer<VarSymbol>();        JCVariableDecl lastParam = null;        for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {            JCVariableDecl param = lastParam = l.head;            assert param.sym != null;            params.append(param.sym);        }        m.params = params.toList();        // mark the method varargs, if necessary        if (lastParam != null && (lastParam.mods.flags & Flags.VARARGS) != 0)            m.flags_field |= Flags.VARARGS;        localEnv.info.scope.leave();        if (chk.checkUnique(tree.pos(), m, enclScope)) {            enclScope.enter(m);        }        annotateLater(tree.mods.annotations, localEnv, m);        if (tree.defaultValue != null)            annotateDefaultValueLater(tree.defaultValue, localEnv, m);    }    /** Create a fresh environment for method bodies.     *  @param tree     The method definition.     *  @param env      The environment current outside of the method definition.     */    Env<AttrContext> methodEnv(JCMethodDecl tree, Env<AttrContext> env) {        Env<AttrContext> localEnv =            env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));        localEnv.enclMethod = tree;        localEnv.info.scope.owner = tree.sym;        if ((tree.mods.flags & STATIC) != 0) localEnv.info.staticLevel++;        return localEnv;    }    public void visitVarDef(JCVariableDecl tree) {        Env<AttrContext> localEnv = env;        if ((tree.mods.flags & STATIC) != 0 ||            (env.info.scope.owner.flags() & INTERFACE) != 0) {            localEnv = env.dup(tree, env.info.dup());            localEnv.info.staticLevel++;        }        attr.attribType(tree.vartype, localEnv);        Scope enclScope = enter.enterScope(env);        VarSymbol v =            new VarSymbol(0, tree.name, tree.vartype.type, enclScope.owner);        v.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, v, tree);        tree.sym = v;        if (tree.init != null) {            v.flags_field |= HASINIT;            if ((v.flags_field & FINAL) != 0 && tree.init.getTag() != JCTree.NEWCLASS)                v.setLazyConstValue(initEnv(tree, env), log, attr, tree.init);        }        if (chk.checkUnique(tree.pos(), v, enclScope)) {            chk.checkTransparentVar(tree.pos(), v, enclScope);            enclScope.enter(v);        }        annotateLater(tree.mods.annotations, localEnv, v);        v.pos = tree.pos;    }    /** 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<AttrContext> initEnv(JCVariableDecl tree, Env<AttrContext> env) {        Env<AttrContext> localEnv = env.dupto(new AttrContextEnv(tree, env.info.dup()));        if (tree.sym.owner.kind == TYP) {            localEnv.info.scope = new Scope.DelegatedScope(env.info.scope);            localEnv.info.scope.owner = tree.sym;        }        if ((tree.mods.flags & STATIC) != 0 ||            (env.enclClass.sym.flags() & INTERFACE) != 0)            localEnv.info.staticLevel++;        return localEnv;    }    /** Default member enter visitor method: do nothing     */    public void visitTree(JCTree tree) {    }            public void visitErroneous(JCErroneous tree) {        memberEnter(tree.errs, env);    }        public Env<AttrContext> getMethodEnv(JCMethodDecl tree, Env<AttrContext> env) {        Env<AttrContext> mEnv = methodEnv(tree, env);	mEnv.info.lint = mEnv.info.lint.augment(tree.sym.attributes_field, tree.sym.flags());        for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail)            mEnv.info.scope.enterIfAbsent(l.head.type.tsym);        for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail)            mEnv.info.scope.enterIfAbsent(l.head.sym);        return mEnv;    }        public Env<AttrContext> getInitEnv(JCVariableDecl tree, Env<AttrContext> env) {        Env<AttrContext> iEnv = initEnv(tree, env);        return iEnv;    }/* ******************************************************************** * Type completion *********************************************************************/    Type attribImportType(JCTree tree, Env<AttrContext> env) {        assert completionEnabled;        try {            // To prevent deep recursion, suppress completion of some            // types.            completionEnabled = false;            return attr.attribType(tree, env);        } finally {            completionEnabled = true;        }    }/* ******************************************************************** * Annotation processing *********************************************************************/    /** Queue annotations for later processing. */    void annotateLater(final List<JCAnnotation> annotations,                       final Env<AttrContext> localEnv,                       final Symbol s) {        if (annotations.isEmpty()) return;        if (s.kind != PCK) s.attributes_field = null; // mark it incomplete for now        annotate.later(new Annotate.Annotator() {                public String toString() {                    return "annotate " + annotations + " onto " + s + " in " + s.owner;                }                public void enterAnnotation() {                    assert s.kind == PCK || s.attributes_field == null;                    JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);                    try {                        if (s.attributes_field != null &&                            s.attributes_field.nonEmpty() &&                            annotations.nonEmpty())                            log.error(annotations.head.pos,                                      "already.annotated",                                      Resolve.kindName(s), s);                        enterAnnotations(annotations, localEnv, s);                    } finally {                        log.useSource(prev);                    }                }            });    }    /**     * Check if a list of annotations contains a reference to     * java.lang.Deprecated.     **/    private boolean hasDeprecatedAnnotation(List<JCAnnotation> annotations) {        for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {            JCAnnotation a = al.head;            if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty())                return true;        }

⌨️ 快捷键说明

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