1
2
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.ASTConditionalExpression;
10 import net.sourceforge.pmd.lang.java.ast.ASTEqualityExpression;
11 import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration;
12 import net.sourceforge.pmd.lang.java.ast.ASTName;
13 import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
14 import net.sourceforge.pmd.lang.java.ast.ASTStatementExpression;
15 import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
16 import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
17 import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
18 import net.sourceforge.pmd.lang.java.typeresolution.TypeHelper;
19
20 public class UseStringBufferForStringAppendsRule extends AbstractJavaRule {
21
22 @Override
23 public Object visit(ASTVariableDeclaratorId node, Object data) {
24 if (!TypeHelper.isA(node, String.class) || node.isArray()) {
25 return data;
26 }
27 Node parent = node.jjtGetParent().jjtGetParent();
28 if (!(parent instanceof ASTLocalVariableDeclaration)) {
29 return data;
30 }
31 for (NameOccurrence no: node.getUsages()) {
32 Node name = no.getLocation();
33 ASTStatementExpression statement = name.getFirstParentOfType(ASTStatementExpression.class);
34 if (statement == null) {
35 continue;
36 }
37 ASTArgumentList argList = name.getFirstParentOfType(ASTArgumentList.class);
38 if (argList != null && argList.getFirstParentOfType(ASTStatementExpression.class) == statement) {
39
40 continue;
41 }
42 ASTEqualityExpression equality = name.getFirstParentOfType(ASTEqualityExpression.class);
43 if (equality != null && equality.getFirstParentOfType(ASTStatementExpression.class) == statement) {
44
45 continue;
46 }
47 ASTConditionalExpression conditional = name.getFirstParentOfType(ASTConditionalExpression.class);
48 if (conditional != null && name.jjtGetParent().jjtGetParent().jjtGetParent() == conditional && conditional.getFirstParentOfType(ASTStatementExpression.class) == statement) {
49
50 continue;
51 }
52 if (statement.jjtGetNumChildren() > 0 && statement.jjtGetChild(0) instanceof ASTPrimaryExpression) {
53 ASTName astName = statement.jjtGetChild(0).getFirstDescendantOfType(ASTName.class);
54 if(astName != null){
55 if (astName.equals(name)) {
56 ASTAssignmentOperator assignmentOperator = statement.getFirstDescendantOfType(ASTAssignmentOperator.class);
57 if (assignmentOperator != null && assignmentOperator.isCompound()) {
58 addViolation(data, assignmentOperator);
59 }
60 } else if(astName.getImage().equals(name.getImage())){
61 ASTAssignmentOperator assignmentOperator = statement.getFirstDescendantOfType(ASTAssignmentOperator.class);
62 if (assignmentOperator != null && !assignmentOperator.isCompound()) {
63 addViolation(data, astName);
64 }
65 }
66 }
67 }
68 }
69 return data;
70 }
71 }