/** * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ package net.sourceforge.pmd.lang.java.rule.strings; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.java.ast.ASTAdditiveExpression; import net.sourceforge.pmd.lang.java.ast.ASTArgumentList; import net.sourceforge.pmd.lang.java.ast.ASTLiteral; import net.sourceforge.pmd.lang.java.ast.ASTName; import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression; import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix; import net.sourceforge.pmd.lang.java.ast.ASTReferenceType; import net.sourceforge.pmd.lang.java.ast.ASTType; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule; import net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration; import net.sourceforge.pmd.lang.symboltable.NameDeclaration; public class UselessStringValueOfRule extends AbstractJavaRule { @Override public Object visit(ASTPrimaryPrefix node, Object data) { if (node.jjtGetNumChildren() == 0 || !(node.jjtGetChild(0) instanceof ASTName)) { return super.visit(node, data); } String image = ((ASTName) node.jjtGetChild(0)).getImage(); if ("String.valueOf".equals(image)) { Node parent = node.jjtGetParent(); if (parent.jjtGetNumChildren() != 2) { return super.visit(node, data); } // skip String.valueOf(anyarraytype[]) ASTArgumentList args = parent.getFirstDescendantOfType(ASTArgumentList.class); if (args != null) { ASTName arg = args.getFirstDescendantOfType(ASTName.class); if (arg != null) { NameDeclaration declaration = arg.getNameDeclaration(); if (declaration != null) { ASTType argType = declaration.getNode().jjtGetParent().jjtGetParent() .getFirstDescendantOfType(ASTType.class); if (argType != null && argType.jjtGetChild(0) instanceof ASTReferenceType && ((ASTReferenceType) argType.jjtGetChild(0)).isArray()) { return super.visit(node, data); } } } } Node gp = parent.jjtGetParent(); if (parent instanceof ASTPrimaryExpression && gp instanceof ASTAdditiveExpression && "+".equals(gp.getImage())) { boolean ok = false; if (gp.jjtGetChild(0) == parent) { ok = !isPrimitive(gp.jjtGetChild(1)); } else { for (int i = 0; !ok && gp.jjtGetChild(i) != parent; i++) { ok = !isPrimitive(gp.jjtGetChild(i)); } } if (ok) { super.addViolation(data, node); return data; } } } return super.visit(node, data); } private static boolean isPrimitive(Node parent) { boolean result = false; if (parent instanceof ASTPrimaryExpression && parent.jjtGetNumChildren() == 1) { Node child = parent.jjtGetChild(0); if (child instanceof ASTPrimaryPrefix && child.jjtGetNumChildren() == 1) { Node gc = child.jjtGetChild(0); if (gc instanceof ASTName) { ASTName name = (ASTName) gc; NameDeclaration nd = name.getNameDeclaration(); if (nd instanceof VariableNameDeclaration && ((VariableNameDeclaration) nd).isPrimitiveType()) { result = true; } } else if (gc instanceof ASTLiteral) { result = !((ASTLiteral) gc).isStringLiteral(); } } } return result; } }