View Javadoc
1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
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  }