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