Checking in Will Sargent's ExceptionAsFlowControlRule

git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@2674 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
Tom Copeland
2004-05-06 18:45:24 +00:00
parent e2540ed5ab
commit 70d96d2c57
5 changed files with 118 additions and 1 deletions

View File

@ -1,3 +1,6 @@
????, 2004 - 1.8:
New rule: ExceptionAsFlowControlRule
April 22, 2004 - 1.7:
Moved development environment to Maven 1.0-RC2.
Fixed bug 925840 - Messages were no longer getting variable names plugged in correctly
@ -7,7 +10,7 @@ Implemented RFE 925839 - Added some more detail to the UseSingletonRule.
Added an optional 'failuresPropertyName' attribute to the Ant task.
Refactored away duplicate copies of XPath rule definitions in regress/, yay!
Removed manifest from jar file; it was only there for the Main-class attribute, and it's not very useful now since PMD has several dependencies.
March 15, 2004 - 1.6:
Fixed bug 895661 - XML reports containing error elements no longer have malformed XML.
Fixed a bug in UnconditionalIfStatement - it no longer flags things like "if (x==true)".

View File

@ -0,0 +1,39 @@
package test.net.sourceforge.pmd.rules.design;
import test.net.sourceforge.pmd.testframework.SimpleAggregatorTst;
import test.net.sourceforge.pmd.testframework.TestDescriptor;
import net.sourceforge.pmd.rules.design.NullAssignmentRule;
import net.sourceforge.pmd.rules.design.ExceptionAsFlowControlRule;
import net.sourceforge.pmd.PMD;
public class ExceptionAsFlowControlRuleTest extends SimpleAggregatorTst {
public void testAll() {
runTests(new TestDescriptor[] {
new TestDescriptor(TEST1, "failure case", 1, new ExceptionAsFlowControlRule()),
new TestDescriptor(TEST2, "normal throw catch", 0, new ExceptionAsFlowControlRule())
});
}
private static final String TEST1 =
"public class Foo {" + PMD.EOL +
" void bar() {" + PMD.EOL +
" try {" + PMD.EOL +
" try {" + PMD.EOL +
" } catch (Exception e) {" + PMD.EOL +
" throw new WrapperException(e);" + PMD.EOL +
" // this is essentially a GOTO to the WrapperException catch block" + PMD.EOL +
" }" + PMD.EOL +
" } catch (WrapperException e) {" + PMD.EOL +
" // do some more stuff " + PMD.EOL +
" }" + PMD.EOL +
" }" + PMD.EOL +
"}";
private static final String TEST2 =
"public class Foo {" + PMD.EOL +
" void bar() {" + PMD.EOL +
" try {} catch (Exception e) {}" + PMD.EOL +
" }" + PMD.EOL +
"}";
}

View File

@ -6,6 +6,31 @@ These are new rules for the next release
</description>
<rule name="ExceptionAsFlowControlRule"
message="Avoid using exceptions as flow control"
class="net.sourceforge.pmd.rules.design.ExceptionAsFlowControlRule">
<description>
Using Exceptions as flow control leads to GOTOish code.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo {
void bar() {
try {
try {
} catch (Exception e) {
throw new WrapperException(e);
// this is essentially a GOTO to the WrapperException catch block
}
} catch (WrapperException e) {
// do some more stuff
}
}
}
]]>
</example>
</rule>
</ruleset>

View File

@ -0,0 +1,49 @@
package net.sourceforge.pmd.rules.design;
import net.sourceforge.pmd.ast.ASTName;
import net.sourceforge.pmd.ast.Node;
import net.sourceforge.pmd.ast.ASTThrowStatement;
import net.sourceforge.pmd.ast.ASTType;
import net.sourceforge.pmd.ast.ASTCatch;
import net.sourceforge.pmd.ast.ASTTryStatement;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.AbstractRule;
import java.util.Iterator;
import java.util.List;
/**
* Catches the use of exception statements as a flow control device.
*
* @author Will Sargent
*/
public class ExceptionAsFlowControlRule extends AbstractRule {
public Object visit(ASTThrowStatement node, Object data) {
String throwName = getThrowsName(node);
for (Node parent = node.jjtGetParent(); parent != null; parent = parent.jjtGetParent()) {
if (parent instanceof ASTTryStatement) {
List list = ((ASTTryStatement) parent).getCatchBlocks();
for (Iterator iter = list.iterator(); iter.hasNext();) {
ASTCatch catchStmt = (ASTCatch) iter.next();
ASTType type = (ASTType) catchStmt.getFormalParameter().findChildrenOfType(ASTType.class).get(0);
ASTName name = (ASTName) type.findChildrenOfType(ASTName.class).get(0);
if (throwName != null && throwName.equals(name.getImage())) {
((RuleContext) data).getReport().addRuleViolation(createRuleViolation((RuleContext) data, name.getBeginLine()));
}
}
}
}
return data;
}
private String getThrowsName(ASTThrowStatement node) {
Node childNode = node;
while (childNode.jjtGetNumChildren() > 0) {
childNode = childNode.jjtGetChild(0);
}
if (childNode instanceof ASTName) {
return ((ASTName) childNode).getImage();
}
return null;
}
}

View File

@ -39,6 +39,7 @@
</subsection>
<subsection name="Contributors">
<ul>
<li>Will Sargent - ExceptionAsFlowControlRule</li>
<li>Bertrand Mollinier Toublet - Bug report which led to platform character set encoding enhancement</li>
<li>Choi Ki Soo - Found bug in XMLRenderer</li>
<li>wedemann - Found bug in RuleSetFactory XPath message variable plugging</li>