UseStringBufferForStringAppendsRule.java
01 package net.sourceforge.pmd.lang.java.rule.optimizations;
02 
03 import net.sourceforge.pmd.lang.ast.Node;
04 import net.sourceforge.pmd.lang.java.ast.ASTArgumentList;
05 import net.sourceforge.pmd.lang.java.ast.ASTAssignmentOperator;
06 import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration;
07 import net.sourceforge.pmd.lang.java.ast.ASTName;
08 import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
09 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() && statement.jjtGetChild(0instanceof 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 }