1 |
| |
2 |
| |
3 |
| |
4 |
| package net.sourceforge.pmd.rules; |
5 |
| |
6 |
| import net.sourceforge.pmd.AbstractRule; |
7 |
| import net.sourceforge.pmd.ast.ASTAdditiveExpression; |
8 |
| import net.sourceforge.pmd.ast.ASTAllocationExpression; |
9 |
| import net.sourceforge.pmd.ast.ASTBlockStatement; |
10 |
| import net.sourceforge.pmd.ast.ASTClassOrInterfaceType; |
11 |
| import net.sourceforge.pmd.ast.ASTLiteral; |
12 |
| import net.sourceforge.pmd.ast.ASTName; |
13 |
| |
14 |
| |
15 |
| |
16 |
| |
17 |
| |
18 |
| |
19 |
| |
20 |
| |
21 |
| |
22 |
| |
23 |
| public final class AvoidConcatenatingNonLiteralsInStringBuffer extends AbstractRule { |
24 |
| |
25 |
8
| public Object visit(ASTAdditiveExpression node, Object data) {
|
26 |
8
| ASTBlockStatement bs = (ASTBlockStatement) node.getFirstParentOfType(ASTBlockStatement.class);
|
27 |
8
| if (bs == null) {
|
28 |
1
| return data;
|
29 |
| } |
30 |
| |
31 |
7
| if (!concatsLiteralStringAndNonLiteral(node)) {
|
32 |
4
| return data;
|
33 |
| } |
34 |
| |
35 |
3
| if (bs.isAllocation()) {
|
36 |
1
| if (isAllocatedStringBuffer(node)) {
|
37 |
1
| addViolation(data, node);
|
38 |
| } |
39 |
2
| } else if (isInStringBufferAppend(node)) {
|
40 |
1
| addViolation(data, node);
|
41 |
| } |
42 |
3
| return data;
|
43 |
| } |
44 |
| |
45 |
7
| private boolean concatsLiteralStringAndNonLiteral(ASTAdditiveExpression node) {
|
46 |
7
| if (!node.containsChildOfType(ASTName.class)) {
|
47 |
2
| return false;
|
48 |
| } |
49 |
5
| ASTLiteral n = (ASTLiteral)node.getFirstChildOfType(ASTLiteral.class);
|
50 |
5
| if (n == null) {
|
51 |
0
| return false;
|
52 |
| } |
53 |
5
| try {
|
54 |
5
| Integer.parseInt(n.getImage());
|
55 |
| } catch (NumberFormatException nfe) { |
56 |
3
| return true;
|
57 |
| } |
58 |
2
| return false;
|
59 |
| } |
60 |
| |
61 |
2
| private boolean isInStringBufferAppend(ASTAdditiveExpression node) {
|
62 |
2
| ASTBlockStatement s = (ASTBlockStatement) node.getFirstParentOfType(ASTBlockStatement.class);
|
63 |
2
| if (s == null) {
|
64 |
0
| return false;
|
65 |
| } |
66 |
2
| ASTName n = (ASTName) s.getFirstChildOfType(ASTName.class);
|
67 |
2
| return n.getImage()!=null && n.getImage().endsWith("append");
|
68 |
| } |
69 |
| |
70 |
1
| private boolean isAllocatedStringBuffer(ASTAdditiveExpression node) {
|
71 |
1
| ASTAllocationExpression ao = (ASTAllocationExpression) node.getFirstParentOfType(ASTAllocationExpression.class);
|
72 |
1
| if (ao == null) {
|
73 |
0
| return false;
|
74 |
| } |
75 |
| |
76 |
1
| ASTClassOrInterfaceType an = (ASTClassOrInterfaceType) ao.getFirstChildOfType(ASTClassOrInterfaceType.class);
|
77 |
1
| return an != null && (an.getImage().endsWith("StringBuffer") || an.getImage().endsWith("StringBuilder"));
|
78 |
| } |
79 |
| } |
80 |
| |