1
2
3
4 package net.sourceforge.pmd.lang.java.rule.strings;
5
6 import net.sourceforge.pmd.lang.ast.Node;
7 import net.sourceforge.pmd.lang.java.ast.ASTAdditiveExpression;
8 import net.sourceforge.pmd.lang.java.ast.ASTArgumentList;
9 import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
10 import net.sourceforge.pmd.lang.java.ast.ASTName;
11 import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
12 import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix;
13 import net.sourceforge.pmd.lang.java.ast.ASTReferenceType;
14 import net.sourceforge.pmd.lang.java.ast.ASTType;
15 import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
16 import net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration;
17 import net.sourceforge.pmd.lang.symboltable.NameDeclaration;
18
19 public class UselessStringValueOfRule extends AbstractJavaRule {
20
21 @Override
22 public Object visit(ASTPrimaryPrefix node, Object data) {
23 if (node.jjtGetNumChildren() == 0 ||
24 !(node.jjtGetChild(0) instanceof ASTName)) {
25 return super.visit(node, data);
26 }
27
28 String image = ((ASTName) node.jjtGetChild(0)).getImage();
29
30 if ("String.valueOf".equals(image)) {
31 Node parent = node.jjtGetParent();
32 if (parent.jjtGetNumChildren() != 2) {
33 return super.visit(node, data);
34 }
35
36 ASTArgumentList args = parent.getFirstDescendantOfType(ASTArgumentList.class);
37 if (args != null) {
38 ASTName arg = args.getFirstDescendantOfType(ASTName.class);
39 if (arg != null) {
40 NameDeclaration declaration = arg.getNameDeclaration();
41 if (declaration != null) {
42 ASTType argType = declaration.getNode().jjtGetParent().jjtGetParent().getFirstDescendantOfType(ASTType.class);
43 if (argType != null
44 && argType.jjtGetChild(0) instanceof ASTReferenceType
45 && ((ASTReferenceType)argType.jjtGetChild(0)).isArray()) {
46 return super.visit(node, data);
47 }
48 }
49 }
50 }
51
52 Node gp = parent.jjtGetParent();
53 if (parent instanceof ASTPrimaryExpression &&
54 gp instanceof ASTAdditiveExpression &&
55 "+".equals(gp.getImage())) {
56 boolean ok = false;
57 if (gp.jjtGetChild(0) == parent) {
58 ok = !isPrimitive(gp.jjtGetChild(1));
59 } else {
60 for (int i = 0; !ok && gp.jjtGetChild(i) != parent; i++) {
61 ok = !isPrimitive(gp.jjtGetChild(i));
62 }
63 }
64 if (ok) {
65 super.addViolation(data, node);
66 return data;
67 }
68 }
69 }
70 return super.visit(node, data);
71 }
72
73 private static boolean isPrimitive(Node parent) {
74 boolean result = false;
75 if (parent instanceof ASTPrimaryExpression && parent.jjtGetNumChildren() == 1) {
76 Node child = parent.jjtGetChild(0);
77 if (child instanceof ASTPrimaryPrefix && child.jjtGetNumChildren() == 1) {
78 Node gc = child.jjtGetChild(0);
79 if (gc instanceof ASTName) {
80 ASTName name = (ASTName) gc;
81 NameDeclaration nd = name.getNameDeclaration();
82 if (nd instanceof VariableNameDeclaration && ((VariableNameDeclaration)nd).isPrimitiveType()) {
83 result = true;
84 }
85 } else if (gc instanceof ASTLiteral) {
86 result = !((ASTLiteral) gc).isStringLiteral();
87 }
88 }
89 }
90 return result;
91 }
92
93 }