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