View Javadoc

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