1 package net.sourceforge.pmd.rules.strings;
2
3 import net.sourceforge.pmd.AbstractRule;
4 import net.sourceforge.pmd.ast.ASTAdditiveExpression;
5 import net.sourceforge.pmd.ast.ASTName;
6 import net.sourceforge.pmd.ast.ASTPrimaryExpression;
7 import net.sourceforge.pmd.ast.ASTPrimaryPrefix;
8 import net.sourceforge.pmd.ast.Node;
9 import net.sourceforge.pmd.ast.SimpleJavaNode;
10 import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
11
12 public class UselessStringValueOf extends AbstractRule {
13
14 public Object visit(ASTPrimaryPrefix node, Object data) {
15 if (node.jjtGetNumChildren() == 0 ||
16 !(node.jjtGetChild(0) instanceof ASTName)) {
17 return super.visit(node, data);
18 }
19
20 String image = ((ASTName) node.jjtGetChild(0)).getImage();
21
22 if ("String.valueOf".equals(image)) {
23 Node parent = node.jjtGetParent();
24 if (parent.jjtGetNumChildren() != 2) {
25 return super.visit(node, data);
26 }
27 SimpleJavaNode gp = (SimpleJavaNode) parent.jjtGetParent();
28 if (parent instanceof ASTPrimaryExpression &&
29 gp instanceof ASTAdditiveExpression &&
30 "+".equals(gp.getImage())) {
31 boolean ok = false;
32 if (gp.jjtGetChild(0) == parent) {
33 ok = !isPrimitive(gp.jjtGetChild(1));
34 } else {
35 for (int i = 0; !ok && gp.jjtGetChild(i) != parent; i++) {
36 ok = !isPrimitive(gp.jjtGetChild(i));
37 }
38 }
39 if (ok) {
40 super.addViolation(data, node);
41 return data;
42 }
43 }
44 }
45 return super.visit(node, data);
46 }
47
48 private static boolean isPrimitive(Node parent) {
49 boolean result = false;
50 if (parent instanceof ASTPrimaryExpression &&
51 parent.jjtGetNumChildren() == 1 &&
52 parent.jjtGetChild(0) instanceof ASTPrimaryPrefix &&
53 parent.jjtGetChild(0).jjtGetNumChildren() == 1 &&
54 parent.jjtGetChild(0).jjtGetChild(0) instanceof ASTName) {
55 ASTName name = (ASTName) parent.jjtGetChild(0).jjtGetChild(0);
56 if (name.getNameDeclaration() instanceof VariableNameDeclaration) {
57 VariableNameDeclaration nd = (VariableNameDeclaration) name.getNameDeclaration();
58 if (nd.isPrimitiveType()) {
59 result = true;
60 }
61 }
62 }
63 return result;
64 }
65
66 }