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

📄 typechecker.java

📁 Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京技术学院的数学和计算机科学系的 Shigeru Chiba 所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
                int type1 = exprType;                right.accept(this);                if (!isConstant(expr, token, left, right))                    computeBinExprType(expr, token, type1);            }        }        else {            /* equation: &&, ||, ==, !=, <=, >=, <, >            */            booleanExpr(expr);        }    }    /* EXPR must be a + expression.     * atPlusExpr() returns non-null if the given expression is string     * concatenation.  The returned value is "new StringBuffer().append..".     */    private Expr atPlusExpr(BinExpr expr) throws CompileError {        ASTree left = expr.oprand1();        ASTree right = expr.oprand2();        if (right == null) {            // this expression has been already type-checked.            // see atBinExpr() above.            left.accept(this);            return null;        }        if (isPlusExpr(left)) {            Expr newExpr = atPlusExpr((BinExpr)left);            if (newExpr != null) {                right.accept(this);                exprType = CLASS;                arrayDim = 0;                className = "java/lang/StringBuffer";                return makeAppendCall(newExpr, right);            }        }        else            left.accept(this);        int type1 = exprType;        int dim1 = arrayDim;        String cname = className;        right.accept(this);        if (isConstant(expr, '+', left, right))            return null;        if ((type1 == CLASS && dim1 == 0 && jvmJavaLangString.equals(cname))            || (exprType == CLASS && arrayDim == 0                && jvmJavaLangString.equals(className))) {            ASTList sbufClass = ASTList.make(new Symbol("java"),                            new Symbol("lang"), new Symbol("StringBuffer"));            ASTree e = new NewExpr(sbufClass, null);            exprType = CLASS;            arrayDim = 0;            className = "java/lang/StringBuffer";            return makeAppendCall(makeAppendCall(e, left), right);        }        else {            computeBinExprType(expr, '+', type1);            return null;        }    }    private boolean isConstant(BinExpr expr, int op, ASTree left,                               ASTree right) throws CompileError    {        left = stripPlusExpr(left);        right = stripPlusExpr(right);        ASTree newExpr = null;        if (left instanceof StringL && right instanceof StringL && op == '+')            newExpr = new StringL(((StringL)left).get()                                  + ((StringL)right).get());        else if (left instanceof IntConst)            newExpr = ((IntConst)left).compute(op, right);        else if (left instanceof DoubleConst)            newExpr = ((DoubleConst)left).compute(op, right);        if (newExpr == null)            return false;       // not a constant expression        else {            expr.setOperator('+');            expr.setOprand1(newExpr);            expr.setOprand2(null);            newExpr.accept(this);   // for setting exprType, arrayDim, ...            return true;        }    }    /* CodeGen.atSwitchStmnt() also calls stripPlusExpr().     */    static ASTree stripPlusExpr(ASTree expr) {        if (expr instanceof BinExpr) {            BinExpr e = (BinExpr)expr;            if (e.getOperator() == '+' && e.oprand2() == null)                return e.getLeft();        }        else if (expr instanceof Expr) {    // note: BinExpr extends Expr.            Expr e = (Expr)expr;            int op = e.getOperator();            if (op == MEMBER) {                ASTree cexpr = getConstantFieldValue((Member)e.oprand2());                if (cexpr != null)                    return cexpr;            }            else if (op == '+' && e.getRight() == null)                return e.getLeft();        }        else if (expr instanceof Member) {            ASTree cexpr = getConstantFieldValue((Member)expr);            if (cexpr != null)                return cexpr;        }        return expr;    }    /**     * If MEM is a static final field, this method returns a constant     * expression representing the value of that field.     */    private static ASTree getConstantFieldValue(Member mem) {        return getConstantFieldValue(mem.getField());    }    public static ASTree getConstantFieldValue(CtField f) {        if (f == null)            return null;        Object value = f.getConstantValue();        if (value == null)            return null;        if (value instanceof String)            return new StringL((String)value);        else if (value instanceof Double || value instanceof Float) {            int token = (value instanceof Double)                        ? DoubleConstant : FloatConstant;            return new DoubleConst(((Number)value).doubleValue(), token);        }        else if (value instanceof Number) {            int token = (value instanceof Long) ? LongConstant : IntConstant;             return new IntConst(((Number)value).longValue(), token);        }        else if (value instanceof Boolean)            return new Keyword(((Boolean)value).booleanValue()                               ? TokenId.TRUE : TokenId.FALSE);        else            return null;    }    private static boolean isPlusExpr(ASTree expr) {        if (expr instanceof BinExpr) {            BinExpr bexpr = (BinExpr)expr;            int token = bexpr.getOperator();            return token == '+';        }        return false;    }    private static Expr makeAppendCall(ASTree target, ASTree arg) {        return CallExpr.makeCall(Expr.make('.', target, new Member("append")),                                 new ASTList(arg));    }    private void computeBinExprType(BinExpr expr, int token, int type1)        throws CompileError    {        // arrayDim should be 0.        int type2 = exprType;        if (token == LSHIFT || token == RSHIFT || token == ARSHIFT)            exprType = type1;        else            insertCast(expr, type1, type2);        if (CodeGen.isP_INT(exprType))            exprType = INT;         // type1 may be BYTE, ...    }    private void booleanExpr(ASTree expr)        throws CompileError    {        int op = CodeGen.getCompOperator(expr);        if (op == EQ) {         // ==, !=, ...            BinExpr bexpr = (BinExpr)expr;            bexpr.oprand1().accept(this);            int type1 = exprType;            int dim1 = arrayDim;            bexpr.oprand2().accept(this);            if (dim1 == 0 && arrayDim == 0)                insertCast(bexpr, type1, exprType);        }        else if (op == '!')            ((Expr)expr).oprand1().accept(this);        else if (op == ANDAND || op == OROR) {            BinExpr bexpr = (BinExpr)expr;            bexpr.oprand1().accept(this);            bexpr.oprand2().accept(this);        }        else                // others            expr.accept(this);        exprType = BOOLEAN;        arrayDim = 0;    }    private void insertCast(BinExpr expr, int type1, int type2)        throws CompileError    {        if (CodeGen.rightIsStrong(type1, type2))            expr.setLeft(new CastExpr(type2, 0, expr.oprand1()));        else            exprType = type1;    }    public void atCastExpr(CastExpr expr) throws CompileError {        String cname = resolveClassName(expr.getClassName());        expr.getOprand().accept(this);        exprType = expr.getType();        arrayDim = expr.getArrayDim();        className = cname;    }    public void atInstanceOfExpr(InstanceOfExpr expr) throws CompileError {        expr.getOprand().accept(this);        exprType = BOOLEAN;        arrayDim = 0;    }    public void atExpr(Expr expr) throws CompileError {        // array access, member access,        // (unary) +, (unary) -, ++, --, !, ~        int token = expr.getOperator();        ASTree oprand = expr.oprand1();        if (token == '.') {            String member = ((Symbol)expr.oprand2()).get();            if (member.equals("length"))                atArrayLength(expr);            else if (member.equals("class"))                                atClassObject(expr);  // .class            else                atFieldRead(expr);        }        else if (token == MEMBER) {     // field read            String member = ((Symbol)expr.oprand2()).get();            if (member.equals("class"))                                atClassObject(expr);  // .class            else                atFieldRead(expr);        }        else if (token == ARRAY)            atArrayRead(oprand, expr.oprand2());        else if (token == PLUSPLUS || token == MINUSMINUS)            atPlusPlus(token, oprand, expr);        else if (token == '!')            booleanExpr(expr);        else if (token == CALL)              // method call            fatal();        else {            oprand.accept(this);            if (!isConstant(expr, token, oprand))                if (token == '-' || token == '~')                    if (CodeGen.isP_INT(exprType))                        exprType = INT;         // type may be BYTE, ...        }    }    private boolean isConstant(Expr expr, int op, ASTree oprand) {        oprand = stripPlusExpr(oprand);        if (oprand instanceof IntConst) {            IntConst c = (IntConst)oprand;            long v = c.get();            if (op == '-')                v = -v;            else if (op == '~')                v = ~v;            else                return false;            c.set(v);        }        else if (oprand instanceof DoubleConst) {            DoubleConst c = (DoubleConst)oprand;            if (op == '-')                c.set(-c.get());            else                return false;        }        else            return false;        expr.setOperator('+');        return true;    }    public void atCallExpr(CallExpr expr) throws CompileError {        String mname = null;        CtClass targetClass = null;        ASTree method = expr.oprand1();        ASTList args = (ASTList)expr.oprand2();        if (method instanceof Member) {            mname = ((Member)method).get();            targetClass = thisClass;        }        else if (method instanceof Keyword) {   // constructor            mname = MethodInfo.nameInit;        // <init>            if (((Keyword)method).get() == SUPER)                targetClass = MemberResolver.getSuperclass(thisClass);            else                targetClass = thisClass;        }        else if (method instanceof Expr) {            Expr e = (Expr)method;            mname = ((Symbol)e.oprand2()).get();            int op = e.getOperator();            if (op == MEMBER)                // static method                targetClass                        = resolver.lookupClass(((Symbol)e.oprand1()).get(),                                               false);            else if (op == '.') {                ASTree target = e.oprand1();                try {

⌨️ 快捷键说明

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