1 package jp.sourceforge.stigmata.birthmarks.cvfv;
7 import java.util.LinkedHashMap;
10 import jp.sourceforge.stigmata.Birthmark;
11 import jp.sourceforge.stigmata.BirthmarkContext;
12 import jp.sourceforge.stigmata.birthmarks.BirthmarkExtractVisitor;
14 import org.objectweb.asm.ClassVisitor;
15 import org.objectweb.asm.FieldVisitor;
16 import org.objectweb.asm.MethodAdapter;
17 import org.objectweb.asm.MethodVisitor;
18 import org.objectweb.asm.Opcodes;
19 import org.objectweb.asm.Type;
25 * @author Haruaki TAMADA
28 public class ConstantValueOfFieldVariableBirthmarkExtractVisitor extends BirthmarkExtractVisitor{
29 private Map<String, TypeAndValueBirthmarkElement> elements = new LinkedHashMap<String, TypeAndValueBirthmarkElement>();
30 private String className;
32 public ConstantValueOfFieldVariableBirthmarkExtractVisitor(ClassVisitor visitor, Birthmark birthmark, BirthmarkContext context){
33 super(visitor, birthmark, context);
37 public void visitEnd(){
38 for(String key: elements.keySet()){
39 addElement(elements.get(key));
45 public void visit(int version, int access, String name, String signature,
46 String superName, String[] interfaces){
47 this.className = name;
49 super.visit(version, access, name, signature, superName, interfaces);
53 public FieldVisitor visitField(int access, String name, String desc,
54 String signature, Object value){
56 FieldVisitor visitor = super.visitField(access, name, desc, signature, value);
58 TypeAndValueBirthmarkElement e = elements.get(name);
60 e = new TypeAndValueBirthmarkElement(desc, value);
67 elements.put(name, e);
73 public MethodVisitor visitMethod(int access, String name, String desc, String signature,
75 MethodVisitor visitor = super.visitMethod(access, name, desc, signature, exceptions);
77 if(name.equals("<init>") || name.equals("<clinit>")){
78 visitor = new MethodAdapter(visitor){
79 private Object constant = null;
82 public void visitIntInsn(int opcode, int operand){
83 if(opcode == Opcodes.BIPUSH || opcode == Opcodes.SIPUSH){
84 constant = new Integer(operand);
86 super.visitIntInsn(opcode, operand);
90 public void visitMethodInsn(int opcode, String owner, String name, String desc){
91 Type type = Type.getReturnType(desc);
92 if(!type.equals(Type.VOID_TYPE)){
95 super.visitMethodInsn(opcode, owner, name, desc);
99 public void visitInsn(int opcode){
100 if(opcode == Opcodes.ICONST_M1) constant = new Integer(-1);
101 else if(opcode == Opcodes.ICONST_0) constant = new Integer(0);
102 else if(opcode == Opcodes.ICONST_1) constant = new Integer(1);
103 else if(opcode == Opcodes.ICONST_2) constant = new Integer(2);
104 else if(opcode == Opcodes.ICONST_3) constant = new Integer(3);
105 else if(opcode == Opcodes.ICONST_4) constant = new Integer(4);
106 else if(opcode == Opcodes.ICONST_5) constant = new Integer(5);
107 else if(opcode == Opcodes.LCONST_0) constant = new Long(0L);
108 else if(opcode == Opcodes.LCONST_1) constant = new Long(1L);
109 else if(opcode == Opcodes.DCONST_0) constant = new Double(0D);
110 else if(opcode == Opcodes.DCONST_1) constant = new Double(1D);
111 else if(opcode == Opcodes.FCONST_0) constant = new Float(0F);
112 else if(opcode == Opcodes.FCONST_1) constant = new Float(1F);
113 else if(opcode == Opcodes.FCONST_2) constant = new Float(2F);
115 super.visitInsn(opcode);
119 public void visitLdcInsn(Object object){
121 super.visitLdcInsn(object);
125 public void visitFieldInsn(int opcode, String owner, String name, String desc){
126 if(className.equals(owner) && opcode == Opcodes.PUTFIELD){
127 TypeAndValueBirthmarkElement e = elements.get(name);
129 e = new TypeAndValueBirthmarkElement(desc, constant);
132 if(e.getValue() == null && constant != null){
133 if(!checkCast(desc, constant)){
136 e.setValue(constant);
139 super.visitFieldInsn(opcode, owner, name, desc);
147 private boolean checkCast(String desc, Object constant){
148 if(constant instanceof Integer){
149 return desc.equals("Ljava/lang/Integer;") ||
150 desc.equals("I") || desc.equals("S") || desc.equals("Z") ||
151 desc.equals("C") || desc.equals("B");
153 else if(constant instanceof Float){
154 return desc.equals("Ljava/lang/Float;") || desc.equals("F");
156 else if(constant instanceof Double){
157 return desc.equals("Ljava/lang/Double;") || desc.equals("D");
159 else if(constant instanceof Long){
160 return desc.equals("Ljava/lang/Long;") || desc.equals("J");
162 else if(constant instanceof String){
163 return desc.equals("Ljava/lang/String;");