View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.lang.java.rule.optimizations;
5   
6   import net.sourceforge.pmd.lang.ast.Node;
7   import net.sourceforge.pmd.lang.java.ast.ASTArgumentList;
8   import net.sourceforge.pmd.lang.java.ast.ASTAssignmentOperator;
9   import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration;
10  import net.sourceforge.pmd.lang.java.ast.ASTName;
11  import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
12  import net.sourceforge.pmd.lang.java.ast.ASTStatementExpression;
13  import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
14  import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
15  import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
16  import net.sourceforge.pmd.lang.java.typeresolution.TypeHelper;
17  
18  public class UseStringBufferForStringAppendsRule extends AbstractJavaRule {
19  
20      @Override
21      public Object visit(ASTVariableDeclaratorId node, Object data) {
22          if (!TypeHelper.isA(node, String.class) || node.isArray()) {
23              return data;
24          }
25          Node parent = node.jjtGetParent().jjtGetParent();
26          if (!(parent instanceof ASTLocalVariableDeclaration)) {
27              return data;
28          }
29          for (NameOccurrence no: node.getUsages()) {
30              Node name = no.getLocation();
31              ASTStatementExpression statement = name.getFirstParentOfType(ASTStatementExpression.class);
32              if (statement == null) {
33                  continue;
34              }
35              ASTArgumentList argList = name.getFirstParentOfType(ASTArgumentList.class);
36              if (argList != null && argList.getFirstParentOfType(ASTStatementExpression.class) == statement) {
37                  // used in method call
38                  continue;
39              }
40              if (statement.jjtGetNumChildren() > 0 && statement.jjtGetChild(0) instanceof ASTPrimaryExpression) {
41                  ASTName astName = statement.jjtGetChild(0).getFirstDescendantOfType(ASTName.class);
42                  if(astName != null){
43                      if (astName.equals(name)) {
44                          ASTAssignmentOperator assignmentOperator = statement.getFirstDescendantOfType(ASTAssignmentOperator.class);
45                          if (assignmentOperator != null && assignmentOperator.isCompound()) {
46                              addViolation(data, assignmentOperator);
47                          }
48                      } else if(astName.getImage().equals(name.getImage())){
49                          ASTAssignmentOperator assignmentOperator = statement.getFirstDescendantOfType(ASTAssignmentOperator.class);
50                          if (assignmentOperator != null && !assignmentOperator.isCompound()) {
51                              addViolation(data, astName);
52                          }
53                      }
54                  }
55              }
56          }
57          return data;
58      }
59  }