1
2
3
4 package net.sourceforge.pmd.lang.java.rule.strings;
5
6 import net.sourceforge.pmd.lang.java.ast.ASTMethodReference;
7 import net.sourceforge.pmd.lang.java.ast.ASTName;
8 import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
9 import net.sourceforge.pmd.lang.java.ast.AbstractJavaNode;
10 import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
11 import net.sourceforge.pmd.lang.java.symboltable.JavaNameOccurrence;
12 import net.sourceforge.pmd.lang.java.typeresolution.TypeHelper;
13 import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
14 import net.sourceforge.pmd.lang.symboltable.ScopedNode;
15
16 public class StringToStringRule extends AbstractJavaRule {
17
18 public Object visit(ASTVariableDeclaratorId node, Object data) {
19 if (!TypeHelper.isA(node.getNameDeclaration(), String.class)) {
20 return data;
21 }
22 boolean isArray = node.isArray();
23 for (NameOccurrence occ: node.getUsages()) {
24 JavaNameOccurrence jocc = (JavaNameOccurrence)occ;
25 NameOccurrence qualifier = jocc.getNameForWhichThisIsAQualifier();
26 if (qualifier != null) {
27 if (!isArray && isNotAMethodReference(qualifier) && qualifier.getImage().indexOf("toString") != -1) {
28 addViolation(data, jocc.getLocation());
29 } else if (isArray && isNotAName(qualifier) && qualifier.getImage().equals("toString")) {
30 addViolation(data, jocc.getLocation());
31 }
32 }
33 }
34 return data;
35 }
36
37 private boolean isNotAMethodReference(NameOccurrence qualifier) {
38 return isNotA(qualifier, ASTMethodReference.class);
39 }
40
41 private boolean isNotAName(NameOccurrence qualifier) {
42 return isNotA(qualifier, ASTName.class);
43 }
44
45 private boolean isNotA(NameOccurrence qualifier, Class<? extends AbstractJavaNode> type) {
46 ScopedNode location = qualifier.getLocation();
47 return location == null || !(type.isAssignableFrom(location.getClass()));
48 }
49 }