1 19 20 package edu.umd.cs.findbugs.ba; 21 22 import java.util.HashSet ; 23 import java.util.IdentityHashMap ; 24 import java.util.Map ; 25 import java.util.Set ; 26 27 import org.apache.bcel.Constants; 28 import org.apache.bcel.classfile.Field; 29 import org.apache.bcel.classfile.JavaClass; 30 import org.apache.bcel.classfile.Method; 31 import org.apache.bcel.generic.ConstantPoolGen; 32 import org.apache.bcel.generic.Instruction; 33 import org.apache.bcel.generic.InstructionHandle; 34 import org.apache.bcel.generic.InstructionList; 35 import org.apache.bcel.generic.MethodGen; 36 import org.apache.bcel.generic.PUTFIELD; 37 38 public class AssignedFieldMap implements Constants { 39 private final ClassContext classContext; 40 private final Map <Method, Set <XField>> assignedFieldSetForMethodMap; 41 42 public AssignedFieldMap(ClassContext classContext) { 43 this.classContext = classContext; 44 this.assignedFieldSetForMethodMap = new IdentityHashMap <Method, Set <XField>>(); 45 } 46 47 public void build() throws ClassNotFoundException { 48 JavaClass jclass = classContext.getJavaClass(); 49 50 Set <XField> assignableFieldSet = new HashSet <XField>(); 53 scanFields(jclass, assignableFieldSet); 54 JavaClass[] superClassList = jclass.getSuperClasses(); 55 if (superClassList != null) { 56 for (JavaClass aSuperClassList : superClassList) { 57 scanFields(aSuperClassList, assignableFieldSet); 58 } 59 } 60 61 Method[] methodList = jclass.getMethods(); 62 for (Method method : methodList) { 63 MethodGen methodGen = classContext.getMethodGen(method); 64 if (methodGen == null) 65 continue; 66 67 scanMethod(method, assignableFieldSet); 68 } 69 } 70 71 public Set <XField> getAssignedFieldSetForMethod(Method method) { 72 Set <XField> set = assignedFieldSetForMethodMap.get(method); 73 if (set == null) { 74 set = new HashSet <XField>(); 75 assignedFieldSetForMethodMap.put(method, set); 76 } 77 return set; 78 } 79 80 private void scanFields(JavaClass jclass, Set <XField> assignableFieldSet) { 81 JavaClass myClass = classContext.getJavaClass(); 82 String myClassName = myClass.getClassName(); 83 String myPackageName = myClass.getPackageName(); 84 85 String superClassName = jclass.getClassName(); 86 String superPackageName = jclass.getPackageName(); 87 88 Field[] fieldList = jclass.getFields(); 89 for (Field field : fieldList) { 90 if (field.isStatic()) 91 continue; 92 boolean assignable; 93 if (field.isPublic() || field.isProtected()) 94 assignable = true; 95 else if (field.isPrivate()) 96 assignable = myClassName.equals(superClassName); 97 else assignable = myPackageName.equals(superPackageName); 99 100 if (assignable) { 101 assignableFieldSet.add(new InstanceField(superClassName, field.getName(), field.getSignature(), 102 field.getAccessFlags())); 103 } 104 } 105 } 106 107 private void scanMethod(Method method, Set <XField> assignableFieldSet) throws ClassNotFoundException { 108 MethodGen methodGen = classContext.getMethodGen(method); 109 if (methodGen == null) return; 110 InstructionList il = methodGen.getInstructionList(); 111 InstructionHandle handle = il.getStart(); 112 113 ConstantPoolGen cpg = methodGen.getConstantPool(); 114 115 while (handle != null) { 116 Instruction ins = handle.getInstruction(); 117 short opcode = ins.getOpcode(); 118 if (opcode == Constants.PUTFIELD) { 119 PUTFIELD putfield = (PUTFIELD) ins; 120 121 XField instanceField = Hierarchy.findXField(putfield, cpg); 122 if (instanceField != null && assignableFieldSet.contains(instanceField)) { 123 Set <XField> assignedFieldSetForMethod = getAssignedFieldSetForMethod(method); 124 assignedFieldSetForMethod.add(instanceField); 125 } 126 } 127 128 handle = handle.getNext(); 129 } 130 } 131 } 132 133 | Popular Tags |