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  }