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  }