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:
@ -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)".
|
||||
|
@ -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 +
|
||||
"}";
|
||||
}
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
Reference in New Issue
Block a user