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

📄 attr.java

📁 GJC(Generic Java Compiler)编译器
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
                Type site = env.enclClass.sym.type;                if (methName == names._super)                    site = site.supertype();                if (site.tag == CLASS) {                    if (site.outer().tag == CLASS) {                        if (tree.meth.tag == Tree.SELECT) {                            Tree qualifier = ((Select) tree.meth).selected;                            chk.checkRefType(qualifier.pos,                                    attribExpr(qualifier, localEnv, site.outer()));                        } else if (methName == names._super) {                            rs.resolveImplicitThis(tree.meth.pos, localEnv, site);                        }                    } else if (tree.meth.tag == Tree.SELECT) {                        log.error(tree.meth.pos, "illegal.qual.not.icls",                                site.tsym.toJava());                    }                    boolean selectSuperPrev =                            ((AttrContext) localEnv.info).selectSuper;                    ((AttrContext) localEnv.info).selectSuper = true;                    Symbol sym = rs.resolveConstructor(tree.meth.pos, localEnv, site,                            argtypes);                    ((AttrContext) localEnv.info).selectSuper = selectSuperPrev;                    TreeInfo.setSymbol(tree.meth, sym);                    List saved = methTemplateSupply.elems;                    Type mpt = newMethTemplate(argtypes);                    checkId(tree.meth, site, sym, env, MTH, mpt);                    methTemplateSupply.elems = saved;                }            }            result = syms.voidType;        } else {            argtypes = attribArgs(tree.args, localEnv);            List saved = methTemplateSupply.elems;            Type mpt = newMethTemplate(argtypes);            Type mtype = attribExpr(tree.meth, localEnv, mpt);            methTemplateSupply.elems = saved;            result = check(tree, mtype.restype(), VAL, pkind, pt);        }    }    /**      * Check that given application node appears as first statement      *  in a constructor call.      *  @param tree   The application node      *  @param env    The environment current at the application.      */    boolean checkFirstConstructorStat(Apply tree, Env env) {        MethodDef enclMethod = env.enclMethod;        if (enclMethod != null && enclMethod.name == names.init) {            Block body = (Block) enclMethod.body;            if (((Tree) body.stats.head).tag == Tree.EXEC &&                    ((Exec) body.stats.head).expr == tree)                return true;        }        log.error(tree.pos, "call.must.be.first.stmt.in.ctor",                TreeInfo.name(tree.meth).toJava());        return false;    }    /**      * Optimization: To avoid allocating a new methodtype for every      *  attribution of an Apply node, we use a reservoir.      */    ListBuffer methTemplateSupply = new ListBuffer();    /**     * Obtain an otherwise unused method type with given argument types.     *  Take it from the reservoir if non-empty, or create a new one.     */    Type newMethTemplate(List argtypes) {        if (methTemplateSupply.elems == methTemplateSupply.last)            methTemplateSupply.append(                    new MethodType(null, null, null, syms.methodClass));        MethodType mt = (Type.MethodType) methTemplateSupply.elems.head;        methTemplateSupply.elems = methTemplateSupply.elems.tail;        mt.argtypes = argtypes;        return mt;    }    public void visitNewClass(NewClass tree) {        Type owntype = syms.errType;        ClassDef cdef = tree.def;        Tree clazz = tree.clazz;        Tree clazzid = clazz;        Tree clazzid1 = clazzid;        if (tree.encl != null) {            Type encltype =                    chk.checkRefType(tree.encl.pos, attribExpr(tree.encl, env));            clazzid1 = make.at(clazz.pos).Select(make.Type(encltype),                    ((Ident) clazzid).name);            clazz = clazzid1;        }        Type clazztype = chk.checkClassType(tree.clazz.pos, attribType(clazz, env));        chk.validate(clazz);        if (tree.encl != null) {            tree.clazz.type = clazztype;            TreeInfo.setSymbol(clazzid, TreeInfo.symbol(clazzid1));            clazzid.type = ((Ident) clazzid).sym.type;            if ((clazztype.tsym.flags() & STATIC) != 0 && !clazztype.isErroneous()) {                log.error(tree.pos, "qualified.new.of.static.class",                        clazztype.tsym.toJava());            }        } else if ((clazztype.tsym.flags() & INTERFACE) == 0 &&                clazztype.outer().tag == CLASS) {            rs.resolveImplicitThis(tree.pos, env, clazztype);        }        List argtypes = attribArgs(tree.args, env);        if (clazztype.tag == CLASS) {            if (cdef == null &&                    (clazztype.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {                log.error(tree.pos, "abstract.cant.be.instantiated",                        clazztype.tsym.toJava());            } else if (cdef != null && (clazztype.tsym.flags() & INTERFACE) != 0) {                if (argtypes.nonEmpty()) {                    log.error(tree.pos, "anon.class.impl.intf.no.args");                    argtypes = Type.emptyList;                } else if (tree.encl != null) {                    log.error(tree.pos, "anon.class.impl.intf.no.qual.for.new");                }            } else {                boolean selectSuperPrev = ((AttrContext) env.info).selectSuper;                if (cdef != null)                    ((AttrContext) env.info).selectSuper = true;                tree.constructor =                        rs.resolveConstructor(tree.pos, env, clazztype, argtypes);                ((AttrContext) env.info).selectSuper = selectSuperPrev;            }            if (cdef != null) {                if (Resolve.isStatic(env))                    cdef.flags |= STATIC;                if ((clazztype.tsym.flags() & INTERFACE) != 0) {                    cdef.implementing = List.make(clazz);                } else {                    cdef.extending = clazz;                }                attribStat(cdef, env.dup(tree));                if (tree.encl != null) {                    tree.args = tree.args.prepend(makeNullCheck(tree.encl));                    argtypes = argtypes.prepend(tree.encl.type);                    tree.encl = null;                }                clazztype = cdef.sym.type;                tree.constructor =                        rs.resolveConstructor(tree.pos, env, clazztype, argtypes);            }            if (tree.constructor != null && tree.constructor.kind == MTH) {                owntype = clazztype;            }        }        result = check(tree, owntype, VAL, pkind, pt);    }    /**      * Make an attributed null check tree.      */    public Tree makeNullCheck(Tree arg) {        Name name = TreeInfo.name(arg);        if (name == names._this || name == names._super)            return arg;        int optag = Tree.NULLCHK;        Unary tree = make.at(arg.pos).Unary(optag, arg);        tree.operator = syms.nullcheck;        tree.type = arg.type;        return tree;    }    public void visitNewArray(NewArray tree) {        Type owntype = syms.errType;        Type elemtype;        if (tree.elemtype != null) {            elemtype = attribType(tree.elemtype, env);            chk.validate(tree.elemtype);            owntype = elemtype;            for (List l = tree.dims; l.nonEmpty(); l = l.tail) {                attribExpr((Tree) l.head, env, syms.intType);                owntype = new ArrayType(owntype, syms.arrayClass);            }        } else {            if (pt.tag == ARRAY) {                elemtype = pt.elemtype();            } else {                if (pt.tag != ERROR) {                    log.error(tree.pos, "illegal.initializer.for.type", pt.toJava());                }                elemtype = syms.errType;            }        }        if (tree.elems != null) {            attribExprs(tree.elems, env, elemtype);            owntype = new ArrayType(elemtype, syms.arrayClass);        }        result = check(tree, owntype, VAL, pkind, pt);    }    public void visitParens(Parens tree) {        Type owntype = attribTree(tree.expr, env, pkind, pt);        result = check(tree, owntype, pkind, pkind, pt);        Symbol sym = TreeInfo.symbol(tree);        if (isType(sym)) {            log.error(tree.pos, "illegal.start.of.expr");        }    }    public void visitAssign(Assign tree) {        Type owntype = attribTree(tree.lhs, env.dup(tree), VAR, pt);        attribExpr(tree.rhs, env, owntype);        result = check(tree, owntype, VAL, pkind, pt);    }    public void visitAssignop(Assignop tree) {        List argtypes = List.make(attribTree(tree.lhs, env, VAR, Type.noType),                attribExpr(tree.rhs, env));        Symbol operator = tree.operator =                rs.resolveOperator(tree.pos, tree.tag - Tree.ASGOffset, env,                argtypes);        Type owntype = (Type) argtypes.head;        if (operator.kind == MTH) {            if (owntype.tag <= DOUBLE)                chk.checkCastable(tree.rhs.pos, operator.type.restype(), owntype);            else if (owntype.tag == CLASS)                chk.checkType(tree.lhs.pos, owntype, syms.stringType);            else                chk.checkType(tree.rhs.pos, operator.type.restype(), owntype);        }        result = check(tree, owntype, VAL, pkind, pt);    }    public void visitUnary(Unary tree) {        Type argtype = (Tree.PREINC <= tree.tag && tree.tag <= Tree.POSTDEC) ?                attribTree(tree.arg, env, VAR, Type.noType) :                chk.checkNonVoid(tree.arg.pos, attribExpr(tree.arg, env));        Symbol operator = tree.operator =                rs.resolveUnaryOperator(tree.pos, tree.tag, env, argtype);        Type owntype = syms.errType;        if (operator.kind == MTH) {            owntype = operator.type.restype();            int opc = ((OperatorSymbol) operator).opcode;            if (argtype.constValue != null) {                Type ctype = cfolder.fold1(opc, argtype);                if (ctype != null) {                    owntype = cfolder.coerce(ctype, owntype);                    if (tree.arg.type.tsym == syms.stringType.tsym) {                        tree.arg.type = syms.stringType;                    }                }            }        }        result = check(tree, owntype, VAL, pkind, pt);    }    public void visitBinary(Binary tree) {        Type left = chk.checkNonVoid(tree.lhs.pos, attribExpr(tree.lhs, env));        Type right = chk.checkNonVoid(tree.lhs.pos, attribExpr(tree.rhs, env));        Symbol operator = tree.operator =                rs.resolveBinaryOperator(tree.pos, tree.tag, env, left, right);        Type owntype = syms.errType;        if (operator.kind == MTH) {            owntype = operator.type.restype();            int opc = ((OperatorSymbol) operator).opcode;            if (opc == ByteCodes.error) {                log.error(tree.lhs.pos, "operator.cant.be.applied",                        treeinfo.operatorName(tree.tag).toJava(),                        left.toJava() + "," + right.toJava());            }            if (left.constValue != null && right.constValue != null) {                Type ctype = cfolder.fold2(opc, left, right);                if (ctype != null) {                    owntype = cfolder.coerce(ctype, owntype);                    if (tree.lhs.type.tsym == syms.stringType.tsym) {                        tree.lhs.type = syms.stringType;                    }                    if (tree.rhs.type.tsym == syms.stringType.tsym) {                        tree.rhs.type = syms.stringType;                    }                }            }            if (opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne) {                if (!left.isCastable(right.erasure()) &&                        !right.isCastable(left.erasure())) {                    log.error(tree.pos, "incomparable.types", left.toJava(),                            right.toJava());                } else {                    chk.checkCompatible(tree.pos, left, right);                }            }        }        result = check(tree, owntype, VAL, pkind, pt);    }    public void visitTypeCast(TypeCast tree) {        Type clazztype = attribType(tree.clazz, env);        Type exprtype = attribExpr(tree.expr, env, Type.noType);        Type owntype = chk.checkCastable(tree.expr.pos, exprtype, clazztype);        if (exprtype.constValue != null)            owntype = cfolder.coerce(exprtype, owntype);        result = check(tree, owntype, VAL, pkind, pt);    }    public void visitTypeTest(TypeTest tree) {        Type exprtype = attribExpr(tree.expr, env);        Type clazztype = chk.checkClassOrArrayType(tree.clazz.pos,                attribType(tree.clazz, env));        chk.checkCastable(tree.expr.pos, exprtype, clazztype);        result = check(tree, syms.booleanType, VAL, pkind, pt);    }    public void visitIndexed(Indexed tree) {        Type owntype = syms.errType;        Type atype = attribExpr(tree.indexed, env);        attribExpr(tree.index, env, syms.intType);        if (atype.tag == ARRAY)            owntype = atype.elemtype();        else if (atype.tag != ERROR)            log.error(tree.pos, "array.req.but.found", atype.toJava());        result = check(tree, owntype, VAR, pkind, pt);    }    public void visitIdent(Ident tree) {        Symbol sym;        if (pt.tag == METHOD) {            sym = rs.resolveMethod(tree.pos, env, tree.name, pt.argtypes());        } else if (tree.sym != null && tree.sym.kind != VAR) {            sym = tree.sym;        } else {            sym = rs.resolveIdent(tree.pos, env, tree.name, pkind);        }        tree.sym = sym;        Env symEnv = env;        boolean noOuterThisPath = false;        if (env.enclClass.sym.owner.kind != PCK &&                (sym.kind & (VAR | MTH | TYP)) != 0 && sym.owner.kind == TYP &&                tree.name != names._this && tree.name != names._super) {            while (symEnv.outer != null && !sym.isMemberOf(symEnv.enclClass.sym)) {                if ((symEnv.enclClass.sym.flags() & NOOUTERTHIS) != 0)                    noOuterThisPath = true;                symEnv = symEnv.outer;            }        }        if (sym.kind == VAR) {            VarSymbol v = (VarSymbol) sym;            checkInit(tree, env, v);            if (v.owner.kind == MTH &&                    v.owner != ((AttrContext) env.info).scope.owner) {                if ((v.flags_field & FINAL) == 0) {                    log.error(tree.pos, "local.var.accessed.from.icls.needs.final",                            v.toJava());                }            }            if (pkind == VAR)

⌨️ 快捷键说明

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