Clover coverage report - PMD - 3.7 Coverage timestamp: Wed May 31 2006 09:25:59 EDT FRAMES NO FRAMES |
file stats: | LOC: | 78 |  | Methods: | 5
| NCLOC: | 64 |  | Classes: | 1
Source file | Conditionals | Statements | Methods | TOTAL
PositionalIteratorRule.java | 79.2% | 93.5% | 100% | 88.3% |

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