Update of /cvsroot/fb-contrib/fb-contrib/src/com/mebigfatguy/fbcontrib/detect
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4247/src/com/mebigfatguy/fbcontrib/detect
Added Files:
AbnormalFinallyBlockReturn.java
Log Message:
new detector, AFBR - initial checkin
--- NEW FILE: AbnormalFinallyBlockReturn.java ---
package com.mebigfatguy.fbcontrib.detect;
import java.util.ArrayList;
import java.util.List;
import org.apache.bcel.classfile.Code;
import org.apache.bcel.classfile.CodeException;
import edu.umd.cs.findbugs.BugInstance;
import edu.umd.cs.findbugs.BugReporter;
import edu.umd.cs.findbugs.BytecodeScanningDetector;
import edu.umd.cs.findbugs.StatelessDetector;
public class AbnormalFinallyBlockReturn extends BytecodeScanningDetector implements StatelessDetector {
private BugReporter bugReporter;
private CodeException[] exc;
private List<FinallyBlockInfo> fbInfo = new ArrayList<FinallyBlockInfo>();
public AbnormalFinallyBlockReturn(final BugReporter bugReporter) {
this.bugReporter = bugReporter;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
public void visitCode(Code obj) {
fbInfo.clear();
exc = obj.getExceptionTable();
if (exc != null) {
for (CodeException ce : exc) {
if ((ce.getCatchType() == 0)
&& (ce.getStartPC() == ce.getHandlerPC())) {
fbInfo.add(new FinallyBlockInfo(ce.getStartPC(), ce.getEndPC()));
}
}
}
if (fbInfo.size() > 0)
super.visitCode(obj);
}
public void sawOpcode(int seen) {
if (fbInfo.size() == 0)
return;
FinallyBlockInfo fbi = fbInfo.get(0);
if ((seen == GOTO) && ((getPC() + 3) == fbi.startPC)) {
fbi.afterFinallyPC = getBranchTarget();
return;
} else if ((seen == ATHROW) && ((getPC() + 1) == fbi.startPC)) {
fbi.afterFinallyPC = getMaxPC() + 1;
return;
}
if (getPC() < fbi.startPC)
return;
if ((getPC() == fbi.startPC) && (fbi.afterFinallyPC == 0)) {
fbInfo.remove(0);
sawOpcode(seen);
return;
}
if (getPC() >= fbi.afterFinallyPC) {
fbInfo.remove(0);
sawOpcode(seen);
return;
}
if (seen == MONITORENTER) {
fbi.monitorCount++;
} else if (seen == MONITOREXIT) {
fbi.monitorCount--;
if (fbi.monitorCount < 0) {
fbInfo.remove(0);
sawOpcode(seen);
return;
}
}
if (((seen >= IRETURN) && (seen <= RETURN)) || (seen == ATHROW)) {
bugReporter.reportBug(new BugInstance( this, "AFBR_ABNORMAL_FINALLY_BLOCK_RETURN", NORMAL_PRIORITY)
.addClass(this)
.addMethod(this)
.addSourceLine(this));
fbInfo.remove(0);
}
}
public static class FinallyBlockInfo
{
public int startPC;
public int endPC;
public int afterFinallyPC;
public int monitorCount;
public FinallyBlockInfo(int start, int end) {
startPC = start;
endPC = end;
afterFinallyPC = 0;
monitorCount = 0;
}
}
}
|