import javassist.bytecode.*;
import javassist.compiler.Javac;
+import javassist.compiler.SymbolTable;
import javassist.compiler.CompileError;
import javassist.compiler.ast.ASTree;
+import javassist.compiler.ast.IntConst;
+import javassist.compiler.ast.DoubleConst;
+import javassist.compiler.ast.StringL;
/**
* An instance of CtField represents a field.
* @see CtClass#getDeclaredFields()
*/
public class CtField extends CtMember {
+ static final String javaLangString = "java.lang.String";
+
protected FieldInfo fieldInfo;
/**
// produce codes for initialization
abstract int compileIfStatic(CtClass type, String name,
Bytecode code, Javac drv) throws CannotCompileException;
+
+ // returns the index of CONSTANT_Integer_info etc
+ // if the value is constant. Otherwise, 0.
+ int getConstantValue(ConstPool cp, CtClass type) { return 0; }
}
static abstract class CodeInitializer0 extends Initializer {
throw new CannotCompileException(e);
}
}
+
+ int getConstantValue2(ConstPool cp, CtClass type, ASTree tree) {
+ if (type.isPrimitive()) {
+ if (tree instanceof IntConst) {
+ long value = ((IntConst)tree).get();
+ if (type == CtClass.doubleType)
+ return cp.addDoubleInfo((double)value);
+ else if (type == CtClass.floatType)
+ return cp.addFloatInfo((float)value);
+ else if (type == CtClass.longType)
+ return cp.addLongInfo(value);
+ else if (type != CtClass.voidType)
+ return cp.addIntegerInfo((int)value);
+ }
+ else if (tree instanceof DoubleConst) {
+ double value = ((DoubleConst)tree).get();
+ if (type == CtClass.floatType)
+ return cp.addFloatInfo((float)value);
+ else if (type == CtClass.doubleType)
+ return cp.addDoubleInfo(value);
+ }
+ }
+ else if (tree instanceof StringL
+ && type.getName().equals(javaLangString))
+ return cp.addStringInfo(((StringL)tree).get());
+
+ return 0;
+ }
}
static class CodeInitializer extends CodeInitializer0 {
void compileExpr(Javac drv) throws CompileError {
drv.compileExpr(expression);
}
+
+ int getConstantValue(ConstPool cp, CtClass type) {
+ try {
+ ASTree t = Javac.parseExpr(expression, new SymbolTable());
+ return getConstantValue2(cp, type, t);
+ }
+ catch (CompileError e) {
+ return 0;
+ }
+ }
}
static class PtreeInitializer extends CodeInitializer0 {
void compileExpr(Javac drv) throws CompileError {
drv.compileExpr(expression);
}
+
+ int getConstantValue(ConstPool cp, CtClass type) {
+ return getConstantValue2(cp, type, expression);
+ }
}
/**
{
int nparam = stringParams.length;
code.addIconst(nparam);
- code.addAnewarray("java.lang.String");
+ code.addAnewarray(javaLangString);
for (int j = 0; j < nparam; ++j) {
code.add(Bytecode.DUP); // dup
code.addIconst(j); // iconst_<j>
code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
return 1; // stack size
}
+
+ int getConstantValue(ConstPool cp, CtClass type) {
+ if (type == CtClass.intType)
+ return cp.addIntegerInfo(value);
+ else
+ return 0;
+ }
}
static class LongInitializer extends Initializer {
code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
return 2; // stack size
}
+
+ int getConstantValue(ConstPool cp, CtClass type) {
+ if (type == CtClass.longType)
+ return cp.addLongInfo(value);
+ else
+ return 0;
+ }
}
static class DoubleInitializer extends Initializer {
code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
return 2; // stack size
}
+
+ int getConstantValue(ConstPool cp, CtClass type) {
+ if (type == CtClass.doubleType)
+ return cp.addDoubleInfo(value);
+ else
+ return 0;
+ }
}
static class StringInitializer extends Initializer {
StringInitializer(String v) { value = v; }
void check(CtClass type) throws CannotCompileException {
- if (!type.getName().equals("java.lang.String"))
+ if (!type.getName().equals(javaLangString))
throw new CannotCompileException("type mismatch");
}
code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
return 1; // stack size
}
+
+ int getConstantValue(ConstPool cp, CtClass type) {
+ if (type.getName().equals(javaLangString))
+ return cp.addStringInfo(value);
+ else
+ return 0;
+ }
}
static class ArrayInitializer extends Initializer {