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