View Javadoc

1   package net.sourceforge.pmd.rules.optimization;
2   
3   import net.sourceforge.pmd.AbstractRule;
4   import net.sourceforge.pmd.ast.ASTAssignmentOperator;
5   import net.sourceforge.pmd.ast.ASTLocalVariableDeclaration;
6   import net.sourceforge.pmd.ast.ASTName;
7   import net.sourceforge.pmd.ast.ASTPrimaryExpression;
8   import net.sourceforge.pmd.ast.ASTStatementExpression;
9   import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
10  import net.sourceforge.pmd.ast.Node;
11  import net.sourceforge.pmd.ast.SimpleNode;
12  import net.sourceforge.pmd.symboltable.NameOccurrence;
13  
14  import java.util.Iterator;
15  
16  public class UseStringBufferForStringAppends extends AbstractRule {
17  
18      public Object visit(ASTVariableDeclaratorId node, Object data) {
19          if (node.getTypeNameNode().jjtGetNumChildren() == 0 || !"String".equals(((SimpleNode) node.getTypeNameNode().jjtGetChild(0)).getImage())) {
20              return data;
21          }
22          Node parent = node.jjtGetParent().jjtGetParent();
23          if (!parent.getClass().equals(ASTLocalVariableDeclaration.class)) {
24              return data;
25          }
26          for (Iterator iter = node.getUsages().iterator(); iter.hasNext();) {
27              NameOccurrence no = (NameOccurrence) iter.next();
28              SimpleNode name = (SimpleNode) no.getLocation();
29              ASTStatementExpression statement = (ASTStatementExpression) name.getFirstParentOfType(ASTStatementExpression.class);
30              if (statement == null) {
31                  continue;
32              }
33              if (statement.jjtGetNumChildren() > 0 && statement.jjtGetChild(0).getClass().equals(ASTPrimaryExpression.class)) {
34                  // FIXME - hm, is there a bug in those methods?
35                  // check that we're looking at the "left hand" node. NB:
36                  // no.isRightHand / no.isLeftHand doesn't look like it works
37                  ASTName astName = (ASTName) ((SimpleNode) statement.jjtGetChild(0)).getFirstChildOfType(ASTName.class);
38                  if (astName != null && astName.equals(name)) {
39                      ASTAssignmentOperator assignmentOperator = (ASTAssignmentOperator) statement.getFirstChildOfType(ASTAssignmentOperator.class);
40                      if (assignmentOperator != null && assignmentOperator.isCompound()) {
41                          addViolation(data, assignmentOperator);
42                      }
43                  }
44              }
45          }
46  
47          return data;
48      }
49  }