[Fb-contrib-commit] SF.net SVN: fb-contrib: [613] trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/de
Brought to you by:
dbrosius
From: <dbr...@us...> - 2006-08-12 17:18:45
|
Revision: 613 Author: dbrosius Date: 2006-08-12 10:18:40 -0700 (Sat, 12 Aug 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=613&view=rev Log Message: ----------- in order for it to be recursion, method has to be called on 'this' -- duh! Modified Paths: -------------- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/TailRecursion.java Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/TailRecursion.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/TailRecursion.java 2006-08-12 15:20:44 UTC (rev 612) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/TailRecursion.java 2006-08-12 17:18:40 UTC (rev 613) @@ -20,10 +20,13 @@ import org.apache.bcel.classfile.Code; import org.apache.bcel.classfile.Method; +import org.apache.bcel.generic.Type; import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.BugReporter; import edu.umd.cs.findbugs.BytecodeScanningDetector; +import edu.umd.cs.findbugs.OpcodeStack; +import edu.umd.cs.findbugs.ba.ClassContext; /** * looks for methods that make a recursive call to itself as the last statement in the @@ -35,8 +38,11 @@ public static final int TAILRECURSIONFUDGE = 6; private BugReporter bugReporter; + private OpcodeStack stack; private int trPCPos; private boolean possibleTailRecursion; + private boolean isStatic; + /** * constructs a TR detector given the reporter to report bugs on @@ -47,6 +53,20 @@ } /** + * implements the visitor to create and clear the stack + * + * @param classContext the context object of the currently parsed class + */ + @Override + public void visitClassContext(ClassContext classContext) { + try { + stack = new OpcodeStack(); + super.visitClassContext(classContext); + } finally { + stack = null; + } + } + /** * implements the visitor to figure the pc where the method call must occur * depending on whether the method returns a value, or not. * @@ -64,6 +84,8 @@ } trPCPos -= TAILRECURSIONFUDGE; possibleTailRecursion = true; + isStatic = obj.isStatic(); + stack.resetForMethodEntry(this); super.visitMethod(obj); } } @@ -76,19 +98,33 @@ */ @Override public void sawOpcode(int seen) { - if (seen == INVOKEVIRTUAL) { - boolean isRecursion = (getMethodName().equals(getNameConstantOperand())) - && (getMethodSig().equals(getSigConstantOperand())) - && (getClassName().equals(getClassConstantOperand())); + try { + stack.mergeJumps(this); - if (isRecursion && possibleTailRecursion && (getPC() >= trPCPos)) { - bugReporter.reportBug(new BugInstance(this, "TR_TAIL_RECURSION", NORMAL_PRIORITY) - .addClass(this) - .addMethod(this) - .addSourceLine(this)); + if (seen == INVOKEVIRTUAL) { + boolean isRecursion = (getMethodName().equals(getNameConstantOperand())) + && (getMethodSig().equals(getSigConstantOperand())) + && (getClassName().equals(getClassConstantOperand())); + + if (isRecursion && !isStatic) { + int numParms = Type.getArgumentTypes(getMethodSig()).length; + if (stack.getStackDepth() > numParms) { + OpcodeStack.Item itm = stack.getStackItem(numParms); + isRecursion = (itm.getRegisterNumber() == 0); + } + } + + if (isRecursion && possibleTailRecursion && (getPC() >= trPCPos)) { + bugReporter.reportBug(new BugInstance(this, "TR_TAIL_RECURSION", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + else + possibleTailRecursion = false; } - else - possibleTailRecursion = false; + } finally { + stack.sawOpcode(this, seen); } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |