01: package net.sourceforge.pmd.rules.optimization;
02:
03: import net.sourceforge.pmd.AbstractRule;
04: import net.sourceforge.pmd.ast.ASTAssignmentOperator;
05: import net.sourceforge.pmd.ast.ASTLocalVariableDeclaration;
06: import net.sourceforge.pmd.ast.ASTName;
07: import net.sourceforge.pmd.ast.ASTPrimaryExpression;
08: import net.sourceforge.pmd.ast.ASTStatementExpression;
09: 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()
23: .equals(ASTLocalVariableDeclaration.class)) {
24: return data;
25: }
26: for (NameOccurrence no : node.getUsages()) {
27: SimpleNode name = no.getLocation();
28: ASTStatementExpression statement = name
29: .getFirstParentOfType(ASTStatementExpression.class);
30: if (statement == null) {
31: continue;
32: }
33: if (statement.jjtGetNumChildren() > 0
34: && statement.jjtGetChild(0).getClass().equals(
35: ASTPrimaryExpression.class)) {
36: ASTName astName = ((SimpleNode) statement
37: .jjtGetChild(0))
38: .getFirstChildOfType(ASTName.class);
39: if (astName != null) {
40: if (astName.equals(name)) {
41: ASTAssignmentOperator assignmentOperator = statement
42: .getFirstChildOfType(ASTAssignmentOperator.class);
43: if (assignmentOperator != null
44: && assignmentOperator.isCompound()) {
45: addViolation(data, assignmentOperator);
46: }
47: } else if (astName.getImage().equals(
48: name.getImage())) {
49: ASTAssignmentOperator assignmentOperator = statement
50: .getFirstChildOfType(ASTAssignmentOperator.class);
51: if (assignmentOperator != null
52: && !assignmentOperator.isCompound()) {
53: addViolation(data, astName);
54: }
55: }
56: }
57: }
58: }
59: return data;
60: }
61: }
|