1 19 20 package edu.umd.cs.findbugs.ba.npe; 21 22 import java.util.BitSet ; 23 import java.util.LinkedList ; 24 import java.util.List ; 25 26 import org.apache.bcel.generic.ConstantPoolGen; 27 import org.apache.bcel.generic.InvokeInstruction; 28 29 import edu.umd.cs.findbugs.SystemProperties; 30 import edu.umd.cs.findbugs.ba.Hierarchy; 31 import edu.umd.cs.findbugs.ba.JavaClassAndMethod; 32 import edu.umd.cs.findbugs.ba.JavaClassAndMethodChooser; 33 import edu.umd.cs.findbugs.ba.XFactory; 34 import edu.umd.cs.findbugs.ba.XMethod; 35 36 45 public class NonNullContractCollector implements JavaClassAndMethodChooser { 46 private static final boolean DEBUG_NULLARG = SystemProperties.getBoolean("fnd.debug.nullarg"); 47 48 private final ParameterNullnessPropertyDatabase nonNullParamDatabase; 49 private final ParameterNullnessPropertyDatabase possiblyNullParamDatabase; 50 private final List <NonNullSpecification> specificationList; 51 52 public NonNullContractCollector(ParameterNullnessPropertyDatabase nonNullParamDatabase, ParameterNullnessPropertyDatabase possiblyNullParamDatabase) { 53 super(); 54 this.nonNullParamDatabase = nonNullParamDatabase; 55 this.possiblyNullParamDatabase = possiblyNullParamDatabase; 56 this.specificationList = new LinkedList <NonNullSpecification>(); 57 } 58 59 public boolean choose(JavaClassAndMethod classAndMethod) { 60 XMethod xmethod = XFactory.createXMethod( 61 classAndMethod.getJavaClass(), classAndMethod.getMethod()); 62 63 NonNullSpecification specification = new NonNullSpecification( 64 classAndMethod, 65 wrapProperty(nonNullParamDatabase.getProperty(xmethod)), 66 wrapProperty(possiblyNullParamDatabase.getProperty(xmethod))); 67 if (DEBUG_NULLARG) { 68 System.out.println("Found specification: " + specification); 69 } 70 specificationList.add(specification); 71 72 return false; 73 } 74 75 public void findContractForCallSite(InvokeInstruction invokeInstruction, ConstantPoolGen cpg) throws ClassNotFoundException { 76 Hierarchy.findInvocationLeastUpperBound(invokeInstruction, cpg, this); 77 } 78 79 public void findContractForMethod(JavaClassAndMethod classAndMethod) throws ClassNotFoundException { 80 String methodName = classAndMethod.getMethod().getName(); 81 String signature = classAndMethod.getMethod().getSignature(); 82 Hierarchy.findMethod(classAndMethod.getJavaClass(), methodName, signature, this); 83 Hierarchy.visitSuperClassMethods(classAndMethod, this); 84 Hierarchy.visitSuperInterfaceMethods(classAndMethod, this); 85 } 86 87 public interface SpecificationBuilder { 88 public boolean checkParam(int param); 89 public void setNonNullParam(int param, NonNullSpecification specification); 90 public void setCheckForNullParam(int param, NonNullSpecification specification); 91 } 92 93 public void checkSpecifications(int numParams, SpecificationBuilder builder) { 94 BitSet checkedParams = new BitSet (); 95 for (NonNullSpecification specification : specificationList) { 96 if (DEBUG_NULLARG) { 97 System.out.println("Check specification: " + specification); 98 } 99 100 paramLoop: 101 for (int i = 0; i < numParams; ++i) { 102 if (DEBUG_NULLARG) { 103 System.out.print("\tParam " + i); 104 } 105 106 if (checkedParams.get(i)) { 107 if (DEBUG_NULLARG) System.out.println(" ==> already checked"); 108 continue paramLoop; 109 } 110 111 if (!builder.checkParam(i)) 112 continue paramLoop; 113 114 if (specification.getCheckForNullProperty().isNonNull(i)) { 117 builder.setCheckForNullParam(i, specification); 119 checkedParams.set(i); 120 } else if (specification.getNonNullProperty().isNonNull(i)) { 121 builder.setNonNullParam(i, specification); 123 checkedParams.set(i); 124 } else { 125 if (DEBUG_NULLARG) System.out.println(" ==> no constraint"); 126 } 127 } 128 } 129 } 130 131 public void getViolationList( 132 int numParams, 133 final BitSet nullArgSet, 134 final List <NonNullParamViolation> violationList, 135 final BitSet violatedParamSet) { 136 137 SpecificationBuilder builder = new SpecificationBuilder() { 138 public boolean checkParam(int param) { 139 if (!argIsNull(param)) { 140 if (DEBUG_NULLARG) System.out.println(" ==> not null"); 141 return false; 142 } 143 return true; 144 } 145 146 public void setNonNullParam(int param, NonNullSpecification specification) { 147 if (DEBUG_NULLARG) System.out.println(" ==> @NonNull violation!"); 148 violationList.add(new NonNullParamViolation(specification.getClassAndMethod(), param)); 149 violatedParamSet.set(param); 150 } 151 152 public void setCheckForNullParam(int param, NonNullSpecification specification) { 153 if (DEBUG_NULLARG) System.out.println(" ==> @CheckForNull"); 154 } 155 156 private boolean argIsNull(int param) { 157 return nullArgSet.get(param); 158 } 159 }; 160 checkSpecifications(numParams, builder); 161 } 162 163 public void getAnnotationSets(int numParams, final BitSet nonNullParamSet, final BitSet possiblyNullParamSet) { 164 SpecificationBuilder builder = new SpecificationBuilder() { 165 public boolean checkParam(int param) { 166 return true; 167 } 168 169 public void setNonNullParam(int param, NonNullSpecification specification) { 170 nonNullParamSet.set(param); 171 } 172 173 public void setCheckForNullParam(int param, NonNullSpecification specification) { 174 possiblyNullParamSet.set(param); 175 } 176 }; 177 checkSpecifications(numParams, builder); 178 } 179 180 static ParameterNullnessProperty wrapProperty(ParameterNullnessProperty property) { 181 return property != null ? property : new ParameterNullnessProperty(); 182 } 183 } 184 | Popular Tags |