1 package jp.sourceforge.stigmata.birthmarks.cvfv;
3 import java.util.LinkedHashMap;
6 import jp.sourceforge.stigmata.Birthmark;
7 import jp.sourceforge.stigmata.BirthmarkContext;
8 import jp.sourceforge.stigmata.birthmarks.BirthmarkExtractVisitor;
10 import org.objectweb.asm.ClassVisitor;
11 import org.objectweb.asm.FieldVisitor;
12 import org.objectweb.asm.MethodAdapter;
13 import org.objectweb.asm.MethodVisitor;
14 import org.objectweb.asm.Opcodes;
15 import org.objectweb.asm.Type;
21 * @author Haruaki TAMADA
23 public class ConstantValueOfFieldVariableBirthmarkExtractVisitor extends BirthmarkExtractVisitor{
24 private Map<String, TypeAndValueBirthmarkElement> elements = new LinkedHashMap<String, TypeAndValueBirthmarkElement>();
25 private String className;
27 public ConstantValueOfFieldVariableBirthmarkExtractVisitor(ClassVisitor visitor, Birthmark birthmark, BirthmarkContext context){
28 super(visitor, birthmark, context);
32 public void visitEnd(){
33 for(String key: elements.keySet()){
34 addElement(elements.get(key));
40 public void visit(int version, int access, String name, String signature,
41 String superName, String[] interfaces){
42 this.className = name;
44 super.visit(version, access, name, signature, superName, interfaces);
48 public FieldVisitor visitField(int access, String name, String desc,
49 String signature, Object value){
51 FieldVisitor visitor = super.visitField(access, name, desc, signature, value);
53 TypeAndValueBirthmarkElement e = elements.get(name);
55 e = new TypeAndValueBirthmarkElement(desc, value);
62 elements.put(name, e);
68 public MethodVisitor visitMethod(int access, String name, String desc, String signature,
70 MethodVisitor visitor = super.visitMethod(access, name, desc, signature, exceptions);
72 if(name.equals("<init>") || name.equals("<clinit>")){
73 visitor = new MethodAdapter(visitor){
74 private Object constant = null;
77 public void visitIntInsn(int opcode, int operand){
78 if(opcode == Opcodes.BIPUSH || opcode == Opcodes.SIPUSH){
79 constant = new Integer(operand);
81 super.visitIntInsn(opcode, operand);
85 public void visitMethodInsn(int opcode, String owner, String name, String desc){
86 Type type = Type.getReturnType(desc);
87 if(!type.equals(Type.VOID_TYPE)){
90 super.visitMethodInsn(opcode, owner, name, desc);
94 public void visitInsn(int opcode){
95 if(opcode == Opcodes.ICONST_M1) constant = new Integer(-1);
96 else if(opcode == Opcodes.ICONST_0) constant = new Integer(0);
97 else if(opcode == Opcodes.ICONST_1) constant = new Integer(1);
98 else if(opcode == Opcodes.ICONST_2) constant = new Integer(2);
99 else if(opcode == Opcodes.ICONST_3) constant = new Integer(3);
100 else if(opcode == Opcodes.ICONST_4) constant = new Integer(4);
101 else if(opcode == Opcodes.ICONST_5) constant = new Integer(5);
102 else if(opcode == Opcodes.LCONST_0) constant = new Long(0L);
103 else if(opcode == Opcodes.LCONST_1) constant = new Long(1L);
104 else if(opcode == Opcodes.DCONST_0) constant = new Double(0D);
105 else if(opcode == Opcodes.DCONST_1) constant = new Double(1D);
106 else if(opcode == Opcodes.FCONST_0) constant = new Float(0F);
107 else if(opcode == Opcodes.FCONST_1) constant = new Float(1F);
108 else if(opcode == Opcodes.FCONST_2) constant = new Float(2F);
110 super.visitInsn(opcode);
114 public void visitLdcInsn(Object object){
116 super.visitLdcInsn(object);
120 public void visitFieldInsn(int opcode, String owner, String name, String desc){
121 if(className.equals(owner) && opcode == Opcodes.PUTFIELD){
122 TypeAndValueBirthmarkElement e = elements.get(name);
124 e = new TypeAndValueBirthmarkElement(desc, constant);
127 if(e.getValue() == null && constant != null){
128 if(!checkCast(desc, constant)){
131 e.setValue(constant);
134 super.visitFieldInsn(opcode, owner, name, desc);
142 private boolean checkCast(String desc, Object constant){
143 if(constant instanceof Integer){
144 return desc.equals("Ljava/lang/Integer;") ||
145 desc.equals("I") || desc.equals("S") || desc.equals("Z") ||
146 desc.equals("C") || desc.equals("B");
148 else if(constant instanceof Float){
149 return desc.equals("Ljava/lang/Float;") || desc.equals("F");
151 else if(constant instanceof Double){
152 return desc.equals("Ljava/lang/Double;") || desc.equals("D");
154 else if(constant instanceof Long){
155 return desc.equals("Ljava/lang/Long;") || desc.equals("J");
157 else if(constant instanceof String){
158 return desc.equals("Ljava/lang/String;");