View Javadoc

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