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.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              // skip String.valueOf(anyarraytype[])
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  }