| 1 19 20 package edu.umd.cs.findbugs.visitclass; 21 22 import java.util.HashSet ; 23 import java.util.Set ; 24 import java.util.regex.Matcher ; 25 import java.util.regex.Pattern ; 26 27 import org.apache.bcel.classfile.Attribute; 28 import org.apache.bcel.classfile.Code; 29 import org.apache.bcel.classfile.CodeException; 30 import org.apache.bcel.classfile.Constant; 31 import org.apache.bcel.classfile.ConstantClass; 32 import org.apache.bcel.classfile.ConstantPool; 33 import org.apache.bcel.classfile.ConstantUtf8; 34 import org.apache.bcel.classfile.Field; 35 import org.apache.bcel.classfile.InnerClass; 36 import org.apache.bcel.classfile.InnerClasses; 37 import org.apache.bcel.classfile.JavaClass; 38 import org.apache.bcel.classfile.LineNumber; 39 import org.apache.bcel.classfile.LineNumberTable; 40 import org.apache.bcel.classfile.LocalVariable; 41 import org.apache.bcel.classfile.LocalVariableTable; 42 import org.apache.bcel.classfile.Method; 43 44 57 public abstract class PreorderVisitor extends BetterVisitor implements Constants2 { 58 59 private ConstantPool constantPool; 61 private JavaClass thisClass; 62 private String className = "none"; 63 private String dottedClassName = "none"; 64 private String packageName = "none"; 65 private String sourceFile = "none"; 66 private String superclassName = "none"; 67 private String dottedSuperclassName = "none"; 68 69 private boolean visitingMethod = false; 71 private String methodSig = "none"; 72 private String dottedMethodSig = "none"; 73 private Method method = null; 74 private String methodName = "none"; 75 private String fullyQualifiedMethodName = "none"; 76 77 private Field field; 79 private boolean visitingField = false; 80 private String fullyQualifiedFieldName = "none"; 81 private String fieldName = "none"; 82 private String fieldSig = "none"; 83 private String dottedFieldSig = "none"; 84 private boolean fieldIsStatic; 85 86 private Code code; 88 89 protected String getStringFromIndex(int i) { 90 ConstantUtf8 name = (ConstantUtf8) constantPool.getConstant(i); 91 return name.getBytes(); 92 } 93 94 protected int asUnsignedByte(byte b) { 95 return 0xff & b; 96 } 97 98 102 public Code getCode() { 103 if (code == null) throw new IllegalStateException ("Not visiting Code"); 104 return code; 105 } 106 107 public Set <String > getSurroundingCaughtExceptions(int pc) { 108 HashSet <String > result = new HashSet <String >(); 109 if (code == null) throw new IllegalStateException ("Not visiting Code"); 110 int size = Integer.MAX_VALUE; 111 if (code.getExceptionTable() == null) return result; 112 for (CodeException catchBlock : code.getExceptionTable()) { 113 int startPC = catchBlock.getStartPC(); 114 int endPC = catchBlock.getEndPC(); 115 if (pc >= startPC && pc <= endPC) { 116 int thisSize = endPC - startPC; 117 if (size > thisSize) { 118 result.clear(); 119 size = thisSize; 120 result.add("C" + catchBlock.getCatchType()); 121 } else if (size == thisSize) 122 result.add("C" + catchBlock.getCatchType()); 123 } 124 } 125 return result; 126 } 127 132 public int getSizeOfSurroundingTryBlock(int pc) { 133 return getSizeOfSurroundingTryBlock(null, pc); 134 } 135 140 public int getSizeOfSurroundingTryBlock(String vmNameOfExceptionClass, int pc) { 141 if (code == null) throw new IllegalStateException ("Not visiting Code"); 142 return Util.getSizeOfSurroundingTryBlock(constantPool, code, vmNameOfExceptionClass, pc); 143 } 144 @Override  146 public void visitCode(Code obj) { 147 code = obj; 148 super.visitCode(obj); 149 CodeException[] exceptions = obj.getExceptionTable(); 150 for (CodeException exception : exceptions) 151 exception.accept(this); 152 Attribute[] attributes = obj.getAttributes(); 153 for (Attribute attribute : attributes) 154 attribute.accept(this); 155 code = null; 156 } 157 158 @Override  160 public void visitConstantPool(ConstantPool obj) { 161 super.visitConstantPool(obj); 162 Constant[] constant_pool = obj.getConstantPool(); 163 for (int i = 1; i < constant_pool.length; i++) { 164 constant_pool[i].accept(this); 165 byte tag = constant_pool[i].getTag(); 166 if ((tag == CONSTANT_Double) || (tag == CONSTANT_Long)) 167 i++; 168 } 169 } 170 171 private void doVisitField(Field field) { 172 if (visitingField) 173 throw new IllegalStateException ("visitField called when already visiting a field"); 174 visitingField = true; 175 this.field = field; 176 try { 177 fieldName = fieldSig = dottedFieldSig = fullyQualifiedFieldName = null; 178 179 fieldIsStatic = field.isStatic(); 180 field.accept(this); 181 Attribute[] attributes = field.getAttributes(); 182 for (Attribute attribute : attributes) 183 attribute.accept(this); 184 } finally { 185 visitingField = false; 186 this.field = null; 187 } 188 } 189 190 public void doVisitMethod(Method method) { 191 if (visitingMethod) 192 throw new IllegalStateException ("doVisitMethod called when already visiting a method"); 193 visitingMethod = true; 194 try { 195 this.method = method; 196 methodName = methodSig = dottedMethodSig = fullyQualifiedMethodName = null; 197 198 this.method.accept(this); 199 Attribute[] attributes = method.getAttributes(); 200 for (Attribute attribute : attributes) 201 attribute.accept(this); 202 } finally { 203 visitingMethod = false; 204 } 205 } 206 207 @Override  209 public void visitInnerClasses(InnerClasses obj) { 210 super.visitInnerClasses(obj); 211 InnerClass[] inner_classes = obj.getInnerClasses(); 212 for (InnerClass inner_class : inner_classes) 213 inner_class.accept(this); 214 } 215 216 public void visitAfter(JavaClass obj) { 217 } 218 219 @Override  221 public void visitJavaClass(JavaClass obj) { 222 setupVisitorForClass(obj); 223 constantPool.accept(this); 224 Field[] fields = obj.getFields(); 225 Method[] methods = obj.getMethods(); 226 Attribute[] attributes = obj.getAttributes(); 227 for (Field field : fields) 228 doVisitField(field); 229 for (Method method1 : methods) 230 doVisitMethod(method1); 231 for (Attribute attribute : attributes) 232 attribute.accept(this); 233 visitAfter(obj); 234 } 235 236 public void setupVisitorForClass(JavaClass obj) { 237 constantPool = obj.getConstantPool(); 238 thisClass = obj; 239 ConstantClass c = (ConstantClass) constantPool.getConstant(obj.getClassNameIndex()); 240 className = getStringFromIndex(c.getNameIndex()); 241 dottedClassName = className.replace('/', '.'); 242 packageName = obj.getPackageName(); 243 sourceFile = obj.getSourceFileName(); 244 superclassName = obj.getSuperclassName(); 245 dottedSuperclassName = superclassName.replace('/', '.'); 246 247 super.visitJavaClass(obj); 248 } 249 250 @Override  251 public void visitLineNumberTable(LineNumberTable obj) { 252 super.visitLineNumberTable(obj); 253 LineNumber[] line_number_table = obj.getLineNumberTable(); 254 for (LineNumber aLine_number_table : line_number_table) 255 aLine_number_table.accept(this); 256 } 257 258 @Override  259 public void visitLocalVariableTable(LocalVariableTable obj) { 260 super.visitLocalVariableTable(obj); 261 LocalVariable[] local_variable_table = obj.getLocalVariableTable(); 262 for (LocalVariable aLocal_variable_table : local_variable_table) 263 aLocal_variable_table.accept(this); 264 } 265 266 268 269 public ConstantPool getConstantPool() { 270 return constantPool; 271 } 272 273 274 public String getClassName() { 275 return className; 276 } 277 278 279 public String getDottedClassName() { 280 return dottedClassName; 281 } 282 283 284 public String getPackageName() { 285 return packageName; 286 } 287 288 289 public String getSourceFile() { 290 return sourceFile; 291 } 292 293 294 public String getSuperclassName() { 295 return superclassName; 296 } 297 298 299 public String getDottedSuperclassName() { 300 return dottedSuperclassName; 301 } 302 303 304 public JavaClass getThisClass() { 305 return thisClass; 306 } 307 308 309 public String getFullyQualifiedMethodName() { 310 if (!visitingMethod) 311 throw new IllegalStateException ("getFullyQualifiedMethodName called while not visiting method"); 312 if (fullyQualifiedMethodName == null) { 313 getDottedSuperclassName(); 314 getMethodName(); 315 getDottedMethodSig(); 316 StringBuffer ref = new StringBuffer (5 + dottedClassName.length() 317 + methodName.length() 318 + dottedMethodSig.length()); 319 320 ref.append(dottedClassName) 321 .append(".") 322 .append(methodName) 323 .append(" : ") 324 .append(dottedMethodSig); 325 fullyQualifiedMethodName = ref.toString(); 326 } 327 return fullyQualifiedMethodName; 328 } 329 330 333 public boolean visitingMethod() { 334 return visitingMethod; 335 } 336 339 public boolean visitingField() { 340 return visitingField; 341 } 342 343 public Field getField() { 344 if (!visitingField) 345 throw new IllegalStateException ("getField called while not visiting method"); 346 return field; 347 } 348 349 public Method getMethod() { 350 if (!visitingMethod) 351 throw new IllegalStateException ("getMethod called while not visiting method"); 352 return method; 353 } 354 355 356 public String getMethodName() { 357 if (!visitingMethod) 358 throw new IllegalStateException ("getMethodName called while not visiting method"); 359 if (methodName == null) 360 methodName = getStringFromIndex(method.getNameIndex()); 361 362 return methodName; 363 } 364 365 static Pattern argumentSignature = Pattern.compile("\\[*([BCDFIJSZ]|L[^;]*;)"); 366 367 public static int getNumberArguments(String signature) { 368 int paren = signature.indexOf(')'); 369 370 if (paren == -1) throw new IllegalArgumentException (signature); 371 Matcher m = argumentSignature.matcher(signature.substring(1, paren)); 372 int result = 0; 373 while(m.find()) 374 result++; 375 return result; 376 377 } 378 379 380 public int getNumberMethodArguments() { 381 return getNumberArguments(getMethodSig()); 382 } 383 384 public String getMethodSig() { 385 if (!visitingMethod) 386 throw new IllegalStateException ("getMethodSig called while not visiting method"); 387 if (methodSig == null) 388 methodSig = getStringFromIndex(method.getSignatureIndex()); 389 return methodSig; 390 } 391 392 393 public String getDottedMethodSig() { 394 if (!visitingMethod) 395 throw new IllegalStateException ("getDottedMethodSig called while not visiting method"); 396 if (dottedMethodSig == null) 397 dottedMethodSig = getMethodSig().replace('/', '.'); 398 return dottedMethodSig; 399 } 400 401 402 public String getFieldName() { 403 if (!visitingField) 404 throw new IllegalStateException ("getFieldName called while not visiting field"); 405 if (fieldName == null) 406 fieldName = getStringFromIndex(field.getNameIndex()); 407 408 409 410 return fieldName; 411 } 412 413 414 public String getFieldSig() { 415 if (!visitingField) 416 throw new IllegalStateException ("getFieldSig called while not visiting field"); 417 if (fieldSig == null) fieldSig = getStringFromIndex(field.getSignatureIndex()); 418 return fieldSig; 419 } 420 421 422 public boolean getFieldIsStatic() { 423 if (!visitingField) 424 throw new IllegalStateException ("getFieldIsStatic called while not visiting field"); 425 return fieldIsStatic; 426 } 427 428 429 public String getFullyQualifiedFieldName() { 430 if (!visitingField) 431 throw new IllegalStateException ("getFullyQualifiedFieldName called while not visiting field"); 432 if (fullyQualifiedFieldName == null) 433 fullyQualifiedFieldName = getDottedClassName() + "." + getFieldName() 434 + " : " + getFieldSig(); 435 return fullyQualifiedFieldName; 436 } 437 438 439 @Deprecated  440 public String getDottedFieldSig() { 441 if (!visitingField) 442 throw new IllegalStateException ("getDottedFieldSig called while not visiting field"); 443 if (dottedFieldSig == null) 444 dottedFieldSig = fieldSig.replace('/', '.'); 445 return dottedFieldSig; 446 } 447 448 } 449 | Popular Tags |