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 import net.sourceforge.pmd.typeresolution.TypeHelper;
14
15 public class UseStringBufferForStringAppends extends AbstractRule {
16
17 public Object visit(ASTVariableDeclaratorId node, Object data) {
18 if (!TypeHelper.isA(node, String.class)) {
19 return data;
20 }
21 Node parent = node.jjtGetParent().jjtGetParent();
22 if (!parent.getClass().equals(ASTLocalVariableDeclaration.class)) {
23 return data;
24 }
25 for (NameOccurrence no: node.getUsages()) {
26 SimpleNode name = no.getLocation();
27 ASTStatementExpression statement = name.getFirstParentOfType(ASTStatementExpression.class);
28 if (statement == null) {
29 continue;
30 }
31 if (statement.jjtGetNumChildren() > 0 && statement.jjtGetChild(0).getClass().equals(ASTPrimaryExpression.class)) {
32 ASTName astName = ((SimpleNode) statement.jjtGetChild(0)).getFirstChildOfType(ASTName.class);
33 if(astName != null){
34 if (astName.equals(name)) {
35 ASTAssignmentOperator assignmentOperator = statement.getFirstChildOfType(ASTAssignmentOperator.class);
36 if (assignmentOperator != null && assignmentOperator.isCompound()) {
37 addViolation(data, assignmentOperator);
38 }
39 } else if(astName.getImage().equals(name.getImage())){
40 ASTAssignmentOperator assignmentOperator = statement.getFirstChildOfType(ASTAssignmentOperator.class);
41 if (assignmentOperator != null && !assignmentOperator.isCompound()) {
42 addViolation(data, astName);
43 }
44 }
45 }
46 }
47 }
48 return data;
49 }
50 }