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() > 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 }
|