memberenter.java

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

JAVA
1,108
字号
        return false;    }    /** Enter a set of annotations. */    private void enterAnnotations(List<JCAnnotation> annotations,                          Env<AttrContext> env,                          Symbol s) {        ListBuffer<Attribute.Compound> buf =            new ListBuffer<Attribute.Compound>();        Set<TypeSymbol> annotated = new HashSet<TypeSymbol>();        if (!skipAnnotations)        for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {            JCAnnotation a = al.head;            Attribute.Compound c = annotate.enterAnnotation(a,                                                            syms.annotationType,                                                            env);            if (c == null) continue;            buf.append(c);            // Note: @Deprecated has no effect on local variables and parameters            if (!c.type.isErroneous()                && s.owner.kind != MTH                && types.isSameType(c.type, syms.deprecatedType))                s.flags_field |= Flags.DEPRECATED;            if (!annotated.add(a.type.tsym))                log.error(a.pos, "duplicate.annotation");        }        s.attributes_field = buf.toList();    }    /** Queue processing of an attribute default value. */    void annotateDefaultValueLater(final JCExpression defaultValue,                                   final Env<AttrContext> localEnv,                                   final MethodSymbol m) {        annotate.later(new Annotate.Annotator() {                public String toString() {                    return "annotate " + m.owner + "." +                        m + " default " + defaultValue;                }                public void enterAnnotation() {                    JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);                    try {                        enterDefaultValue(defaultValue, localEnv, m);                    } finally {                        log.useSource(prev);                    }                }            });    }    /** Enter a default value for an attribute method. */    private void enterDefaultValue(final JCExpression defaultValue,                                   final Env<AttrContext> localEnv,                                   final MethodSymbol m) {        m.defaultValue = annotate.enterAttributeValue(m.type.getReturnType(),                                                      defaultValue,                                                      localEnv);    }/* ******************************************************************** * Source completer *********************************************************************/    /** Complete entering a class.     *  @param sym         The symbol of the class to be completed.     */    public void complete(Symbol sym) throws CompletionFailure {        // Suppress some (recursive) MemberEnter invocations        if (!completionEnabled) {            // Re-install same completer for next time around and return.            assert (sym.flags() & Flags.COMPOUND) == 0;            sym.completer = this;            return;        }        ClassSymbol c = (ClassSymbol)sym;        ClassType ct = (ClassType)c.type;        Env<AttrContext> env = enter.typeEnvs.get(c);        JCClassDecl tree = (JCClassDecl)env.tree;        boolean wasFirst = isFirst;        isFirst = false;        JavaFileObject prev = log.useSource(env.toplevel.sourcefile);        try {            // Save class environment for later member enter (2) processing.            halfcompleted.append(env);            // If this is a toplevel-class, make sure any preceding import            // clauses have been seen.            if (c.owner.kind == PCK) {                memberEnter(env.toplevel, env.enclosing(JCTree.TOPLEVEL));                todo.append(env);            }            // Mark class as not yet attributed.            c.flags_field |= UNATTRIBUTED;            if (c.owner.kind == TYP)                c.owner.complete();            // create an environment for evaluating the base clauses            Env<AttrContext> baseEnv = baseEnv(tree, env);            // Determine supertype.            Type supertype =                (tree.extending != null)                ? attr.attribBase(tree.extending, baseEnv, true, false, true)                : ((tree.mods.flags & Flags.ENUM) != 0 && !target.compilerBootstrap(c))                ? attr.attribBase(enumBase(tree.pos, c), baseEnv,                                  true, false, false)                : (c.fullname == names.java_lang_Object)                ? Type.noType                : syms.objectType;            ct.supertype_field = supertype;            // Determine interfaces.            ListBuffer<Type> interfaces = new ListBuffer<Type>();            Set<Type> interfaceSet = new HashSet<Type>();            List<JCExpression> interfaceTrees = tree.implementing;            if ((tree.mods.flags & Flags.ENUM) != 0 && target.compilerBootstrap(c)) {                // add interface Comparable<T>                interfaceTrees =                    interfaceTrees.prepend(make.Type(new ClassType(syms.comparableType.getEnclosingType(),                                                                   List.of(c.type),                                                                   syms.comparableType.tsym)));                // add interface Serializable                interfaceTrees =                    interfaceTrees.prepend(make.Type(syms.serializableType));            }            for (JCExpression iface : interfaceTrees) {                Type i = attr.attribBase(iface, baseEnv, false, true, true);                if (i.tag == CLASS) {                    interfaces.append(i);                    chk.checkNotRepeated(iface.pos(), types.erasure(i), interfaceSet);                }            }            if ((c.flags_field & ANNOTATION) != 0)                ct.interfaces_field = List.of(syms.annotationType);            else                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.implementing.head.pos(),                                       ct.interfaces_field.head);                    ct.interfaces_field = List.nil();                }            }            // Annotations.            // In general, we cannot fully process annotations yet,  but we            // can attribute the annotation types and then check to see if the            // @Deprecated annotation is present.            attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);            if (hasDeprecatedAnnotation(tree.mods.annotations))                c.flags_field |= DEPRECATED;            annotateLater(tree.mods.annotations, baseEnv, c);            attr.attribTypeVariables(tree.typarams, baseEnv);            chk.checkNonCyclic(tree.pos(), c.type);            // Add default constructor if needed.            if ((c.flags() & INTERFACE) == 0 &&                !TreeInfo.hasConstructors(tree.defs)) {                List<Type> argtypes = List.nil();                List<Type> typarams = List.nil();                List<Type> thrown = List.nil();                long ctorFlags = 0;                boolean based = false;                if (c.name.len == 0) {                    JCNewClass nc = (JCNewClass)env.next.tree;                    if (nc.constructor != null) {                        Type superConstrType = types.memberType(c.type,                                                                nc.constructor);                        argtypes = superConstrType.getParameterTypes();                        typarams = superConstrType.getTypeArguments();                        ctorFlags = nc.constructor.flags() & VARARGS;                        if (nc.encl != null) {                            argtypes = argtypes.prepend(nc.encl.type);                            based = true;                        }                        thrown = superConstrType.getThrownTypes();                    }                }                JCTree constrDef = DefaultConstructor(make.at(tree.pos), c,                                                    typarams, argtypes, thrown,                                                    ctorFlags, based);                tree.defs = tree.defs.prepend(constrDef);            }            // If this is a class, enter symbols for this and super into            // current scope.            if ((c.flags_field & INTERFACE) == 0) {                VarSymbol thisSym =                    new VarSymbol(FINAL | HASINIT, names._this, c.type, c);                thisSym.pos = Position.FIRSTPOS;                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;                    env.info.scope.enter(superSym);                }            }            // check that no package exists with same fully qualified name,            // but admit classes in the unnamed package which have the same            // name as a top-level package.            if (checkClash &&                c.owner.kind == PCK && c.owner != syms.unnamedPackage &&                reader.packageExists(c.fullname))                {                    log.error(tree.pos, "clash.with.pkg.of.same.name", c);                }        } catch (CompletionFailure ex) {            chk.completionError(tree.pos(), ex);        } finally {            log.useSource(prev);        }        // Enter all member fields and methods of a set of half completed        // classes in a second phase.        if (wasFirst) {            try {                while (halfcompleted.nonEmpty()) {                    finish(halfcompleted.next());                }            } finally {                isFirst = true;            }            // commit pending annotations            annotate.flush();        }    }    private Env<AttrContext> baseEnv(JCClassDecl tree, Env<AttrContext> env) {        Scope typaramScope = new Scope(tree.sym);        if (tree.typarams != null)            for (List<JCTypeParameter> typarams = tree.typarams;                 typarams.nonEmpty();                 typarams = typarams.tail)                typaramScope.enter(typarams.head.type.tsym);        Env<AttrContext> outer = env.outer; // the base clause can't see members of this class        Env<AttrContext> localEnv = outer.dup(tree, outer.info.dup(typaramScope));        localEnv.baseClause = true;        localEnv.outer = outer;        localEnv.info.isSelfCall = false;        return localEnv;    }    /** Enter member fields and methods of a class     *  @param env        the environment current for the class block.     */    private void finish(Env<AttrContext> env) {        JavaFileObject prev = log.useSource(env.toplevel.sourcefile);        try {            JCClassDecl tree = (JCClassDecl)env.tree;            finishClass(tree, env);        } finally {            log.useSource(prev);        }    }    /** Generate a base clause for an enum type.     *  @param pos              The position for trees and diagnostics, if any     *  @param c                The class symbol of the enum     */    private JCExpression enumBase(int pos, ClassSymbol c) {        JCExpression result = make.at(pos).            TypeApply(make.QualIdent(syms.enumSym),                      List.<JCExpression>of(make.Type(c.type)));        return result;    }/* *************************************************************************** * tree building ****************************************************************************/    /** 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?     */    JCTree DefaultConstructor(TreeMaker make,                            ClassSymbol c,                            List<Type> typarams,                            List<Type> argtypes,                            List<Type> thrown,                            long flags,                            boolean based) {        List<JCVariableDecl> params = make.Params(argtypes, syms.noSymbol);        List<JCStatement> stats = List.nil();        if (c.type != syms.objectType)            stats = stats.prepend(SuperCall(make, typarams, params, based));        if ((c.flags() & ENUM) != 0 &&            (types.supertype(c.type).tsym == syms.enumSym ||             target.compilerBootstrap(c))) {            // constructors of true enums are private            flags = (flags & ~AccessFlags) | PRIVATE | GENERATEDCONSTR;        } else            flags |= (c.flags() & AccessFlags) | GENERATEDCONSTR;        if (c.name.len == 0) flags |= ANONCONSTR;        JCTree result = make.MethodDef(            make.Modifiers(flags),            names.init,            null,            make.TypeParams(typarams),            params,            make.Types(thrown),            make.Block(0, stats),            null);        return result;    }    /** 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 typarams  The type parameters that need to be passed to super     *  @param based   Is first parameter a this$n?     */    JCExpressionStatement SuperCall(TreeMaker make,                   List<Type> typarams,                   List<JCVariableDecl> params,                   boolean based) {        JCExpression meth;        if (based) {            meth = make.Select(make.Ident(params.head), names._super);            params = params.tail;        } else {            meth = make.Ident(names._super);        }        List<JCExpression> typeargs = typarams.nonEmpty() ? make.Types(typarams) : null;        return make.Exec(make.Apply(typeargs, meth, make.Idents(params)));    }}

⌨️ 快捷键说明

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