package net.sourceforge.pmd.rules.design; import net.sourceforge.pmd.AbstractRule; import net.sourceforge.pmd.RuleContext; import net.sourceforge.pmd.ast.ASTCatch; import net.sourceforge.pmd.ast.ASTName; import net.sourceforge.pmd.ast.ASTThrowStatement; import net.sourceforge.pmd.ast.ASTTryStatement; import net.sourceforge.pmd.ast.ASTType; import net.sourceforge.pmd.ast.Node; 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; } }