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

📄 attr.java

📁 GJC(Generic Java Compiler)编译器
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
                checkAssignable(tree.pos, v, null, env);        }        if ((((AttrContext) symEnv.info).isSelfCall || noOuterThisPath) &&                (sym.kind & (VAR | MTH)) != 0 && sym.owner.kind == TYP &&                (sym.flags() & STATIC) == 0) {            chk.earlyRefError(tree.pos, sym.kind == VAR ? sym : thisSym(env));        }        result = checkId(tree, env.enclClass.sym.type, sym, env, pkind, pt);    }    public void visitSelect(Select tree) {        int skind = 0;        if (tree.name == names._this || tree.name == names._super ||                tree.name == names._class) {            skind = TYP;        } else {            if ((pkind & PCK) != 0)                skind = skind | PCK;            if ((pkind & TYP) != 0)                skind = skind | TYP | PCK;            if ((pkind & (VAL | MTH)) != 0)                skind = skind | VAL | TYP;        }        Type site = attribTree(tree.selected, env, skind, Infer.anyPoly);        Symbol sitesym = TreeInfo.symbol(tree.selected);        boolean selectSuperPrev = ((AttrContext) env.info).selectSuper;        ((AttrContext) env.info).selectSuper = sitesym != null &&                (sitesym.name == names._super || sitesym.kind == TYP);        Symbol sym = selectSym(tree, site, env, pt, pkind);        tree.sym = sym;        if (sym.kind == VAR) {            VarSymbol v = (VarSymbol) sym;            evalInit(v);            if (pkind == VAR)                checkAssignable(tree.pos, v, tree.selected, env);        }        if (isType(sym) && (sitesym == null || (sitesym.kind & (TYP | PCK)) == 0)) {            tree.type = check(tree.selected, pt,                    sitesym == null ? VAL : sitesym.kind, TYP | PCK, pt);        }        if (((AttrContext) env.info).selectSuper) {            if ((sym.flags() & STATIC) == 0 && sym.name != names._this &&                    sym.name != names._super) {                if (sitesym.name == names._super) {                    rs.checkNonAbstract(tree.pos, sym);                } else if (sym.kind == VAR || sym.kind == MTH) {                    rs.access(new Resolve.StaticError(sym), tree.pos, site,                            sym.name, true);                }                if (site.isRaw()) {                    Type site1 = env.enclClass.sym.type.asSuper(site.tsym);                    if (site1 != null)                        site = site1;                }            }            if (((AttrContext) env.info).isSelfCall && tree.name == names._this &&                    site.tsym == env.enclClass.sym) {                chk.earlyRefError(tree.pos, sym);            }        }        ((AttrContext) env.info).selectSuper = selectSuperPrev;        result = checkId(tree, site, sym, env, pkind, pt);        ((AttrContext) env.info).tvars = Type.emptyList;    }    /**      * Determine symbol referenced by a Select expression,      *      *  @param tree   The select tree.      *  @param site   The type of the selected expression,      *  @param env    The current environment.      *  @param pt     The current prototype.      *  @param pkind  The expected kind(s) of the Select expression.      */    private Symbol selectSym(Select tree, Type site, Env env, Type pt, int pkind) {        int pos = tree.pos;        Name name = tree.name;        switch (site.tag) {        case PACKAGE:            return rs.access(rs.findIdentInPackage(env, site.tsym, name, pkind),                    pos, site, name, true);        case ARRAY:        case CLASS:            if (pt.tag == METHOD) {                return rs.resolveQualifiedMethod(pos, env, site, name, pt.argtypes());            } else if (name == names._this || name == names._super) {                return rs.resolveSelf(pos, env, site.tsym, name);            } else if (name == names._class) {                return new VarSymbol(STATIC | PUBLIC | FINAL, names._class,                        syms.classType, site.tsym);            } else {                return rs.access(rs.findIdentInType(env, site, name, pkind), pos,                        site, name, true);            }        case ERROR:            return new ErrorType(name, site.tsym).tsym;        default:            if (name == names._class) {                return new VarSymbol(STATIC | PUBLIC | FINAL, names._class,                        syms.classType, site.tsym);            } else {                log.error(pos, "cant.deref", site.toJava());                return syms.errSymbol;            }        }    }    /**      * Determine type of identifier or select expression and check that      *  (1) the referenced symbol is not deprecated      *  (2) the symbol's type is safe (@see checkSafe)      *  (3) if symbol is a variable, check that its type and kind are      *      compatible with the prototype and protokind.      *  (4) if symbol is an instance field of a raw type,      *      which is being assigned to, issue an unchecked warning if its      *      type changes under erasure.      *  (5) if symbol is an instance method of a raw type, issue an      *      unchecked warning if its argument types change under erasure.      *  If checks succeed:      *    If symbol is a constant, return its constant type      *    else if symbol is a method, return its result type      *    otherwise return its type.      *  Otherwise return errType.      *      *  @param tree       The syntax tree representing the identifier      *  @param site       If this is a select, the type of the selected      *                    expression, otherwise the type of the current class.      *  @param sym        The symbol representing the identifier.      *  @param env        The current environment.      *  @param pkind      The set of expected kinds.      *  @param pt         The expected type.      */    Type checkId(Tree tree, Type site, Symbol sym, Env env, int pkind, Type pt) {        Type owntype;        switch (sym.kind) {        case TYP:            owntype = sym.type;            if (owntype.tag == CLASS) {                Type ownOuter = owntype.outer();                if (ownOuter.tag == CLASS && site != ownOuter) {                    Type normSite = site;                    if (normSite.tag == CLASS)                        normSite = site.asOuterSuper(ownOuter.tsym);                    if (normSite != ownOuter)                        owntype = new ClassType(normSite, Type.emptyList,                                owntype.tsym);                }            }            break;        case VAR:            VarSymbol v = (VarSymbol) sym;            owntype = (sym.owner.kind == TYP && sym.name != names._this &&                    sym.name != names._super) ? site.memberType(sym) : sym.type;            if (v.constValue != null && isStaticReference(tree))                owntype = owntype.constType(v.constValue);            break;        case MTH:            owntype = rs.instantiate(env, site, sym, pt.argtypes());            if (owntype == null && Type.isDerivedRaw(pt.argtypes()) &&                    !((AttrContext) env.info).rawArgs) {                ((AttrContext) env.info).rawArgs = true;                owntype = rs.instantiate(env, site, sym, pt.argtypes());                ((AttrContext) env.info).rawArgs = false;            }            if (owntype == null) {                log.error(tree.pos, "internal.error.cant.instantiate",                        sym.toJava(), site.toJava(), Type.toJavaList(pt.argtypes()));            }            break;        case PCK:        case ERR:            owntype = sym.type;            break;        default:            throw new AssertionError("unexpected kind: " + sym.kind +                    " in tree " + tree);        }        if (sym.name != names.init && (sym.flags() & DEPRECATED) != 0 &&                (((AttrContext) env.info).scope.owner.flags() & DEPRECATED) ==                0 && sym.outermostClass() !=                ((AttrContext) env.info).scope.owner.outermostClass())            chk.warnDeprecated(tree.pos, sym);        return check(tree, owntype, sym.kind, pkind, pt);    }    /**      * Check that variable is initialized and evaluate the variable's      *  initializer, if not yet done. Also check that variable is not      *  referenced before it is defined.      *  @param tree    The tree making up the variable reference.      *  @param env     The current environment.      *  @param v       The variable's symbol.      */    private void checkInit(Ident tree, Env env, VarSymbol v) {        if (v.pos > tree.pos && v.owner.kind == TYP &&                canOwnInitializer(((AttrContext) env.info).scope.owner) &&                v.owner == ((AttrContext) env.info).scope.owner.enclClass() &&                ((v.flags() & STATIC) != 0) == Resolve.isStatic(env) &&                (env.tree.tag != Tree.ASSIGN ||                TreeInfo.skipParens(((Assign) env.tree).lhs) != tree))            log.error(tree.pos, "illegal.forward.ref");        evalInit(v);    }    /**      * Can the given symbol be the owner of code which forms part      *  if class initialization? This is the case if the symbol is      *  a type or field, or if the symbol is the synthetic method.      *  owning a block.      */    private boolean canOwnInitializer(Symbol sym) {        return (sym.kind & (VAR | TYP)) != 0 ||                (sym.kind == MTH && (sym.flags() & BLOCK) != 0);    }    /**      * Evaluate a final variable's initializer, unless this has already been      *  done, and set variable's constant value, if the initializer is      *  constant.      */    public void evalInit(VarSymbol v) {        if (v.constValue instanceof AttrContextEnv) {            AttrContextEnv evalEnv = (AttrContextEnv) v.constValue;            Name prev = log.useSource(evalEnv.toplevel.sourcefile);            v.constValue = null;            Type itype = attribExpr(((VarDef) evalEnv.tree).init, evalEnv, v.type);            if (itype.constValue != null)                v.constValue = cfolder.coerce(itype, v.type).constValue;            log.useSource(prev);        }    }    public void visitLiteral(Literal tree) {        result = check(tree, litType(tree.typetag).constType(tree.value), VAL,                pkind, pt);    }    /**      * Return the type of a literal with given type tag.      */    Type litType(int tag) {        return (tag == CLASS) ? syms.stringType : syms.typeOfTag[tag];    }    public void visitTypeIdent(TypeIdent tree) {        result = check(tree, syms.typeOfTag[tree.typetag], TYP, pkind, pt);    }    public void visitTypeArray(TypeArray tree) {        Type etype = attribType(tree.elemtype, env);        result = check(tree, new ArrayType(etype, syms.arrayClass), TYP, pkind, pt);    }    public void visitErroneous(Erroneous tree) {        result = tree.type = syms.errType;    }    /**      * Default visitor method for all other trees.      */    public void visitTree(Tree tree) {        throw new AssertionError();    }    /**      * Main method: attribute class definition associated with given class symbol.      *  reporting completion failures at the given position.      *  @param pos The source position at which completion errors are to be      *             reported.      *  @param c   The class symbol whose definition will be attributed.      */    public void attribClass(int pos, ClassSymbol c) {        try {            attribClass(c);        } catch (CompletionFailure ex) {            chk.completionError(pos, ex);        }    }    /**      * Attribute class definition associated with given class symbol.      *  @param c   The class symbol whose definition will be attributed.      */    void attribClass(ClassSymbol c) throws CompletionFailure {        if (c.type.tag == ERROR)            return;        chk.checkNonCyclic(Position.NOPOS, c.type);        Type st = c.type.supertype();        if (st.tag == CLASS)            attribClass((ClassSymbol) st.tsym);        if (c.owner.kind == TYP && c.owner.type.tag == CLASS)            attribClass((ClassSymbol) c.owner);        if ((c.flags_field & UNATTRIBUTED) != 0) {            c.flags_field &= ~UNATTRIBUTED;            Env env = (Env) enter.classEnvs.remove(c);            Name prev = log.useSource(c.sourcefile);            try {                attribClassBody(env, c);            }            finally { log.useSource(prev);                    } }    }    /**      * Finish the attribution of a class.      */    private void attribClassBody(Env env, ClassSymbol c) {        ClassDef tree = (ClassDef) env.tree;        assert c == tree.sym;        chk.validate(tree.extending);        chk.validate(tree.implementing);        if ((c.flags() & (ABSTRACT | INTERFACE)) == 0) {            if (!retrofit)                chk.checkAllDefined(tree.pos, c);        } else            chk.checkCompatibleSupertypes(tree.pos, c.type);        tree.type = c.type;        chk.checkImplementations(tree);        for (List l = tree.defs; l.nonEmpty(); l = l.tail) {            attribStat((Tree) l.head, env);            if (c.owner.kind != PCK &&                    ((c.flags() & STATIC) == 0 || c.name == names.empty) &&                    (TreeInfo.flags((Tree) l.head) & (STATIC | INTERFACE)) != 0) {                Symbol sym = null;                if (((Tree) l.head).tag == Tree.VARDEF)                    sym = ((VarDef) l.head).sym;                if (sym == null || sym.kind != VAR ||                        ((VarSymbol) sym).constValue == null)                    log.error(((Tree) l.head).pos, "icls.cant.have.static.decl");            }        }        chk.checkCyclicConstructors(tree);    }}

⌨️ 快捷键说明

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