1 package net.sourceforge.pmd.rules.design;
2
3 import net.sourceforge.pmd.AbstractRule;
4 import net.sourceforge.pmd.RuleContext;
5 import net.sourceforge.pmd.ast.ASTCatch;
6 import net.sourceforge.pmd.ast.ASTName;
7 import net.sourceforge.pmd.ast.ASTThrowStatement;
8 import net.sourceforge.pmd.ast.ASTTryStatement;
9 import net.sourceforge.pmd.ast.ASTType;
10 import net.sourceforge.pmd.ast.Node;
11
12 import java.util.Iterator;
13 import java.util.List;
14
15 /***
16 * Catches the use of exception statements as a flow control device.
17 *
18 * @author Will Sargent
19 */
20 public class ExceptionAsFlowControlRule extends AbstractRule {
21 public Object visit(ASTThrowStatement node, Object data) {
22 String throwName = getThrowsName(node);
23 for (Node parent = node.jjtGetParent(); parent != null; parent = parent.jjtGetParent()) {
24 if (parent instanceof ASTTryStatement) {
25 List list = ((ASTTryStatement) parent).getCatchBlocks();
26 for (Iterator iter = list.iterator(); iter.hasNext();) {
27 ASTCatch catchStmt = (ASTCatch) iter.next();
28 ASTType type = (ASTType) catchStmt.getFormalParameter().findChildrenOfType(ASTType.class).get(0);
29 ASTName name = (ASTName) type.findChildrenOfType(ASTName.class).get(0);
30 if (throwName != null && throwName.equals(name.getImage())) {
31 ((RuleContext) data).getReport().addRuleViolation(createRuleViolation((RuleContext) data, name.getBeginLine()));
32 }
33 }
34 }
35 }
36 return data;
37 }
38
39 private String getThrowsName(ASTThrowStatement node) {
40 Node childNode = node;
41 while (childNode.jjtGetNumChildren() > 0) {
42 childNode = childNode.jjtGetChild(0);
43 }
44 if (childNode instanceof ASTName) {
45 return ((ASTName) childNode).getImage();
46 }
47 return null;
48 }
49 }