git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@128 30ef5769-5b8d-40dd-aea6-55b5d6557bb3tags/rel_3_17_1_ga
@@ -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 |
@@ -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> |
@@ -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 |
@@ -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); } |
@@ -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); } |
@@ -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); | |||
} | |||
} |
@@ -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) { |
@@ -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); | |||
} | |||
} |