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.ASTName;
6 import net.sourceforge.pmd.ast.ASTWhileStatement;
7 import net.sourceforge.pmd.ast.SimpleNode;
8
9 import java.util.ArrayList;
10 import java.util.Iterator;
11 import java.util.List;
12
13 public class PositionalIteratorRule extends AbstractRule {
14
15 public Object visit(ASTWhileStatement node, Object data) {
16 if (hasNameAsChild((SimpleNode) node.jjtGetChild(0))) {
17 String exprName = getName((SimpleNode) node.jjtGetChild(0));
18 if (exprName.indexOf(".hasNext") != -1 && node.jjtGetNumChildren() > 1) {
19
20 SimpleNode loopBody = (SimpleNode) node.jjtGetChild(1);
21 List names = new ArrayList();
22 collectNames(getVariableName(exprName), names, loopBody);
23 int nextCount = 0;
24 for (Iterator i = names.iterator(); i.hasNext();) {
25 String name = (String) i.next();
26 if (name.indexOf(".next") != -1) {
27 nextCount++;
28 }
29 }
30
31 if (nextCount > 1) {
32 RuleContext ctx = (RuleContext) data;
33 ctx.getReport().addRuleViolation(createRuleViolation(ctx, node.getBeginLine()));
34 }
35
36 }
37 }
38 return null;
39 }
40
41 private String getVariableName(String exprName) {
42 return exprName.substring(0, exprName.indexOf('.'));
43 }
44
45 private void collectNames(String target, List names, SimpleNode node) {
46 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
47 SimpleNode child = (SimpleNode) node.jjtGetChild(i);
48 if (child.jjtGetNumChildren() > 0) {
49 collectNames(target, names, child);
50 } else {
51 if (child instanceof ASTName && child.getImage().indexOf(".") != -1 && target.equals(getVariableName(child.getImage()))) {
52 names.add(child.getImage());
53 }
54 }
55 }
56 }
57
58 private boolean hasNameAsChild(SimpleNode node) {
59 while (node.jjtGetNumChildren() > 0) {
60 if (node.jjtGetChild(0) instanceof ASTName) {
61 return true;
62 }
63 return hasNameAsChild((SimpleNode) node.jjtGetChild(0));
64 }
65 return false;
66 }
67
68 private String getName(SimpleNode node) {
69 while (node.jjtGetNumChildren() > 0) {
70 if (node.jjtGetChild(0) instanceof ASTName) {
71 return ((ASTName) node.jjtGetChild(0)).getImage();
72 }
73 return getName((SimpleNode) node.jjtGetChild(0));
74 }
75 throw new IllegalArgumentException("Check with hasNameAsChild() first!");
76 }
77 }
This page was automatically generated by Maven