]> source.dussan.org Git - javassist.git/commitdiff
implemented CtField#getConstantValue().
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>
Mon, 30 Aug 2004 17:10:34 +0000 (17:10 +0000)
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>
Mon, 30 Aug 2004 17:10:34 +0000 (17:10 +0000)
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@128 30ef5769-5b8d-40dd-aea6-55b5d6557bb3

src/main/javassist/CtField.java
src/main/javassist/bytecode/ConstPool.java
src/main/javassist/bytecode/FieldInfo.java
src/main/javassist/compiler/ast/CastExpr.java
src/main/javassist/compiler/ast/CondExpr.java
src/main/javassist/compiler/ast/DoubleConst.java
src/main/javassist/compiler/ast/Expr.java
src/main/javassist/compiler/ast/IntConst.java

index baf018126b09520f242306ff5b97f31a7777ca5d..bbf76338a9b6bf20b682fd9548573cdf67820c6f 100644 (file)
@@ -244,6 +244,42 @@ public class CtField extends CtMember {
         fieldInfo.setDescriptor(Descriptor.of(clazz));
     }
 
+    /**
+     * Returns the value of this field if it is a constant field.
+     * This method works only if the field type is a primitive type
+     * or <code>String</code> type.  Otherwise, it returns <code>null</code>.
+     * A constant field is <code>static</code> and <code>final</code>.
+     *
+     * @return  a <code>Integer</code>, <code>Long</code>, <code>Float</code>,
+     *          <code>Double</code>, or <code>String</code> object
+     *          representing the constant value. 
+     *          <code>null</code> if it is not a constant field
+     *          or if the field type is not a primitive type
+     *          or <code>String</code>.
+     */
+    public Object getConstantValue() {
+        int index = fieldInfo.getConstantValue();
+        if (index == 0)
+            return null;
+
+        ConstPool cp = fieldInfo.getConstPool();
+        switch (cp.getTag(index)) {
+            case ConstPool.CONST_Long :
+                return new Long(cp.getLongInfo(index));
+            case ConstPool.CONST_Float :
+                return new Float(cp.getFloatInfo(index));
+            case ConstPool.CONST_Double :
+                return new Double(cp.getDoubleInfo(index));
+            case ConstPool.CONST_Integer :
+                return new Integer(cp.getIntegerInfo(index));
+            case ConstPool.CONST_String :
+                return cp.getStringInfo(index);
+            default :
+                throw new RuntimeException("bad tag: " + cp.getTag(index)
+                                           + " at " + index);
+        }
+    }
+
     /**
      * Obtains an attribute with the given name.
      * If that attribute is not found in the class file, this
index 6f0b2bef071133654b179c7710e99759b980760a..920ac703e9c7fa3106674bc1962272bd3df87b36 100644 (file)
@@ -68,7 +68,7 @@ public final class ConstPool {
     /**
      * <code>CONSTANT_Float</code>
      */
-    public static final int CONST_Float = IntegerInfo.tag;
+    public static final int CONST_Float = FloatInfo.tag;
 
     /**
      * <code>CONSTANT_Long</code>
index 54ae1ba6211f3dec4bbc9bb2933e7d0f0091d469..ff45f1ba60ea517abee27b4ae53b7d2c23a76bc8 100644 (file)
@@ -60,7 +60,15 @@ public final class FieldInfo {
     }
 
     void prune(ConstPool cp) {
-        attribute = null;
+        int index = getConstantValue();
+        if (index == 0)
+            attribute = null;
+        else {
+            index = constPool.copy(index, cp, null);
+            attribute = new LinkedList();
+            attribute.add(new ConstantAttribute(cp, index));
+        }
+
         name = cp.addUtf8Info(getName());
         descriptor = cp.addUtf8Info(getDescriptor());
         constPool = cp;
@@ -125,6 +133,24 @@ public final class FieldInfo {
             descriptor = constPool.addUtf8Info(desc);
     }
 
+    /**
+     * Finds a ConstantValue attribute and returns the index into
+     * the <code>constant_pool</code> table.
+     *
+     * @return 0    if a ConstantValue attribute is not found.
+     */
+    public int getConstantValue() {
+        if ((accessFlags & AccessFlag.STATIC) == 0)
+            return 0;
+
+        ConstantAttribute attr
+            = (ConstantAttribute)getAttribute(ConstantAttribute.tag);
+        if (attr == null)
+            return 0;
+        else
+            return attr.getConstantValue();
+    }
+
     /**
      * Returns all the attributes.
      * A new element can be added to the returned list
index f390d943e92ecf2ddf3c547284c8ac750c05cfe3..06565b38f8cdd295909d14d3014b7a6ad01d733d 100644 (file)
@@ -47,6 +47,8 @@ public class CastExpr extends ASTList implements TokenId {
 
     public ASTree getOprand() { return getRight().getLeft(); }
 
+    public void setOprand(ASTree t) { getRight().setLeft(t); }
+
     public String getTag() { return "cast:" + castType + ":" + arrayDim; }
 
     public void accept(Visitor v) throws CompileError { v.atCastExpr(this); }
index 5eb786f3f48cd6e01cfbc175121a8eab1a61cfa9..f20da60232a9482c2e2a6befce36f1272057fa41 100644 (file)
@@ -27,6 +27,8 @@ public class CondExpr extends ASTList {
 
     public ASTree condExpr() { return head(); }
 
+    public void setCond(ASTree t) { setHead(t); }
+
     public ASTree thenExpr() { return tail().head(); }
 
     public void setThen(ASTree t) { tail().setHead(t); } 
index b706371482f6002753e50327e00c036b3a0bf47c..27de8878c1f5b0a67a3f4b173ba92dd0f440ed96 100644 (file)
@@ -16,6 +16,7 @@
 package javassist.compiler.ast;
 
 import javassist.compiler.CompileError;
+import javassist.compiler.TokenId;
 
 /**
  * Double constant.
@@ -28,6 +29,8 @@ public class DoubleConst extends ASTree {
 
     public double get() { return value; }
 
+    public void set(double v) { value = v; }
+
     /* Returns DoubleConstant or FloatConstant
      */
     public int getType() { return type; }
@@ -37,4 +40,55 @@ public class DoubleConst extends ASTree {
     public void accept(Visitor v) throws CompileError {
         v.atDoubleConst(this);
     }
+
+    public ASTree compute(int op, ASTree right) {
+        if (right instanceof IntConst)
+            return compute0(op, (IntConst)right);
+        else if (right instanceof DoubleConst)
+            return compute0(op, (DoubleConst)right);
+        else
+            return null;
+    }
+
+    private DoubleConst compute0(int op, DoubleConst right) {
+        int newType;
+        if (this.type == TokenId.DoubleConstant
+            || right.type == TokenId.DoubleConstant)
+            newType = TokenId.DoubleConstant;
+        else
+            newType = TokenId.FloatConstant;
+
+        return compute(op, this.value, right.value, newType);
+    }
+
+    private DoubleConst compute0(int op, IntConst right) {
+        return compute(op, this.value, (double)right.value, this.type);
+    }
+
+    private static DoubleConst compute(int op, double value1, double value2,
+                                       int newType)
+    {
+        double newValue;
+        switch (op) {
+        case '+' :
+            newValue = value1 + value2;
+            break;
+        case '-' :
+            newValue = value1 - value2;
+            break;
+        case '*' :
+            newValue = value1 * value2;
+            break;
+        case '/' :
+            newValue = value1 / value2;
+            break;
+        case '%' :
+            newValue = value1 % value2;
+            break;
+        default :
+            return null;
+        }
+
+        return new DoubleConst(newValue, newType);
+    }
 }
index 88fc09e63c3c9c3fbefdfa0bfd507f15b6d8408b..aafe8a75d273f3ad87efd6923986a0be965fee2d 100644 (file)
@@ -52,6 +52,10 @@ public class Expr extends ASTList implements TokenId {
 
     public ASTree oprand1() { return getLeft(); }
 
+    public void setOprand1(ASTree expr) {
+        setLeft(expr);
+    }
+
     public ASTree oprand2() { return getRight().getLeft(); }
 
     public void setOprand2(ASTree expr) {
index d90f1438232a1ad00e30a2e8438598545ca45ae8..b6204e1f4ccfa6ec8d00a0b0990372c0e5a8a636 100644 (file)
@@ -16,6 +16,7 @@
 package javassist.compiler.ast;
 
 import javassist.compiler.CompileError;
+import javassist.compiler.TokenId;
 
 /**
  * Integer constant.
@@ -28,6 +29,8 @@ public class IntConst extends ASTree {
 
     public long get() { return value; }
 
+    public void set(long v) { value = v; }
+
     /* Returns IntConstant, CharConstant, or LongConstant.
      */
     public int getType() { return type; }
@@ -37,4 +40,99 @@ public class IntConst extends ASTree {
     public void accept(Visitor v) throws CompileError {
         v.atIntConst(this);
     }
+
+    public ASTree compute(int op, ASTree right) {
+        if (right instanceof IntConst)
+            return compute0(op, (IntConst)right);
+        else if (right instanceof DoubleConst)
+            return compute0(op, (DoubleConst)right);
+        else
+            return null;
+    }
+
+    private IntConst compute0(int op, IntConst right) {
+        int type1 = this.type;
+        int type2 = right.type;
+        int newType;
+        if (type1 == TokenId.LongConstant || type2 == TokenId.LongConstant)
+            newType = TokenId.LongConstant;
+        else if (type1 == TokenId.CharConstant
+                 && type2 == TokenId.CharConstant)
+            newType = TokenId.CharConstant;
+        else
+            newType = TokenId.IntConstant;
+
+        long value1 = this.value;
+        long value2 = right.value;
+        long newValue;
+        switch (op) {
+        case '+' :
+            newValue = value1 + value2;
+            break;
+        case '-' :
+            newValue = value1 - value2;
+            break;
+        case '*' :
+            newValue = value1 * value2;
+            break;
+        case '/' :
+            newValue = value1 / value2;
+            break;
+        case '%' :
+            newValue = value1 % value2;
+            break;
+        case '|' :
+            newValue = value1 | value2;
+            break;
+        case '^' :
+            newValue = value1 ^ value2;
+            break;
+        case '&' :
+            newValue = value1 & value2;
+            break;
+        case TokenId.LSHIFT :
+            newValue = value << (int)value2;
+            newType = type1;
+            break;
+        case TokenId.RSHIFT :
+            newValue = value >> (int)value2;
+            newType = type1;
+            break;
+        case TokenId.ARSHIFT :
+            newValue = value >>> (int)value2;
+            newType = type1;
+            break;
+        default :
+            return null;
+        }
+
+        return new IntConst(newValue, newType);
+    }
+
+    private DoubleConst compute0(int op, DoubleConst right) {
+        double value1 = (double)this.value;
+        double value2 = right.value;
+        double newValue;
+        switch (op) {
+        case '+' :
+            newValue = value1 + value2;
+            break;
+        case '-' :
+            newValue = value1 - value2;
+            break;
+        case '*' :
+            newValue = value1 * value2;
+            break;
+        case '/' :
+            newValue = value1 / value2;
+            break;
+        case '%' :
+            newValue = value1 % value2;
+            break;
+        default :
+            return null;
+        }
+
+        return new DoubleConst(newValue, right.type);
+    }
 }