1 19 20 package edu.umd.cs.findbugs.detect; 21 22 23 import edu.umd.cs.findbugs.*; 24 25 import org.apache.bcel.classfile.*; 26 27 public class FindFinalizeInvocations extends BytecodeScanningDetector implements StatelessDetector { 28 private static final boolean DEBUG = SystemProperties.getBoolean("ffi.debug"); 29 30 private BugReporter bugReporter; 31 32 public FindFinalizeInvocations(BugReporter bugReporter) { 33 this.bugReporter = bugReporter; 34 } 35 36 37 38 boolean sawSuperFinalize; 39 40 @Override 41 public void visit(Method obj) { 42 if (DEBUG) System.out.println("FFI: visiting " + getFullyQualifiedMethodName()); 43 if (getMethodName().equals("finalize") 44 && getMethodSig().equals("()V") 45 && (obj.getAccessFlags() & (ACC_PUBLIC)) != 0 46 ) 47 bugReporter.reportBug(new BugInstance(this, "FI_PUBLIC_SHOULD_BE_PROTECTED", NORMAL_PRIORITY).addClassAndMethod(this)); 48 } 49 50 @Override 51 public void visit(Code obj) { 52 sawSuperFinalize = false; 53 super.visit(obj); 54 if (!getMethodName().equals("finalize") 55 || !getMethodSig().equals("()V")) 56 return; 57 String overridesFinalizeIn 58 = Lookup.findSuperImplementor(getDottedClassName(), 59 "finalize", 60 "()V", 61 bugReporter); 62 boolean superHasNoFinalizer = overridesFinalizeIn.equals("java.lang.Object"); 63 if (obj.getCode().length == 1) { 65 if (superHasNoFinalizer) { 66 if (!getMethod().isFinal()) 67 bugReporter.reportBug(new BugInstance(this, "FI_EMPTY", NORMAL_PRIORITY).addClassAndMethod(this)); 68 } else 69 bugReporter.reportBug(new BugInstance(this, "FI_NULLIFY_SUPER", NORMAL_PRIORITY) 70 .addClassAndMethod(this) 71 .addClass(overridesFinalizeIn)); 72 } else if (obj.getCode().length == 5 && sawSuperFinalize) 73 bugReporter.reportBug(new BugInstance(this, "FI_USELESS", NORMAL_PRIORITY).addClassAndMethod(this)); 74 else if (!sawSuperFinalize && !superHasNoFinalizer) 75 bugReporter.reportBug(new BugInstance(this, "FI_MISSING_SUPER_CALL", NORMAL_PRIORITY).addClassAndMethod(this) 76 .addClass(overridesFinalizeIn)); 77 } 78 79 @Override 80 public void sawOpcode(int seen) { 81 if (seen == INVOKEVIRTUAL && getNameConstantOperand().equals("finalize")) 82 bugReporter.reportBug(new BugInstance(this, "FI_EXPLICIT_INVOCATION", 83 getMethodName().equals("finalize") && getMethodSig().equals("()V") ? HIGH_PRIORITY : NORMAL_PRIORITY) 84 .addClassAndMethod(this) 85 .addCalledMethod(this).describe("METHOD_CALLED") 86 .addSourceLine(this, getPC())); 87 if (seen == INVOKESPECIAL && getNameConstantOperand().equals("finalize")) 88 sawSuperFinalize = true; 89 } 90 } 91 | Popular Tags |