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.symboltable;
5   
6   import java.util.ArrayList;
7   import java.util.List;
8   import java.util.StringTokenizer;
9   
10  import net.sourceforge.pmd.PMD;
11  import net.sourceforge.pmd.lang.java.ast.ASTArguments;
12  import net.sourceforge.pmd.lang.java.ast.ASTMemberSelector;
13  import net.sourceforge.pmd.lang.java.ast.ASTMethodReference;
14  import net.sourceforge.pmd.lang.java.ast.ASTName;
15  import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
16  import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix;
17  import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix;
18  import net.sourceforge.pmd.lang.java.ast.JavaNode;
19  import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
20  
21  public class NameFinder {
22  
23      private List<JavaNameOccurrence> names = new ArrayList<>();
24  
25      public NameFinder(ASTPrimaryExpression node) {
26          ASTPrimaryPrefix prefix = (ASTPrimaryPrefix) node.jjtGetChild(0);
27          if (prefix.usesSuperModifier()) {
28              add(new JavaNameOccurrence(prefix, "super"));
29          } else if (prefix.usesThisModifier()) {
30              add(new JavaNameOccurrence(prefix, "this"));
31          }
32          for (int i = 0; i < node.jjtGetNumChildren(); i++) {
33              checkForNameChild((JavaNode)node.jjtGetChild(i));
34          }
35      }
36  
37      public List<JavaNameOccurrence> getNames() {
38          return names;
39      }
40  
41      private void checkForNameChild(JavaNode node) {
42          if (node.getImage() != null) {
43              add(new JavaNameOccurrence(node, node.getImage()));
44          }
45          if (node.jjtGetNumChildren() > 0 && node.jjtGetChild(0) instanceof ASTName) {
46              ASTName grandchild = (ASTName) node.jjtGetChild(0);
47              for (StringTokenizer st = new StringTokenizer(grandchild.getImage(), "."); st.hasMoreTokens();) {
48                  add(new JavaNameOccurrence(grandchild, st.nextToken()));
49              }
50          }
51          if (node.jjtGetNumChildren() > 1 && node.jjtGetChild(1) instanceof ASTMethodReference) {
52              ASTMethodReference methodRef = (ASTMethodReference) node.jjtGetChild(1);
53              add(new JavaNameOccurrence(methodRef, methodRef.getImage()));
54          }
55          if (node instanceof ASTPrimarySuffix) {
56              ASTPrimarySuffix suffix = (ASTPrimarySuffix) node;
57              if (suffix.isArguments()) {
58                  JavaNameOccurrence occurrence = names.get(names.size() - 1);
59                  occurrence.setIsMethodOrConstructorInvocation();
60                  ASTArguments args = (ASTArguments) ((ASTPrimarySuffix) node).jjtGetChild(0);
61                  occurrence.setArgumentCount(args.getArgumentCount());
62              } else if (suffix.jjtGetNumChildren() == 1 && suffix.jjtGetChild(0) instanceof ASTMemberSelector) {
63                  ASTMemberSelector member = (ASTMemberSelector) suffix.jjtGetChild(0);
64                  if (member.jjtGetNumChildren() == 1 && member.jjtGetChild(0) instanceof ASTMethodReference) {
65                      ASTMethodReference methodRef = (ASTMethodReference) member.jjtGetChild(0);
66                      add(new JavaNameOccurrence(methodRef, methodRef.getImage()));
67                  } else {
68                      add(new JavaNameOccurrence(member, member.getImage()));
69                  }
70              }
71          }
72      }
73  
74      private void add(JavaNameOccurrence name) {
75          names.add(name);
76          if (names.size() > 1) {
77              JavaNameOccurrence qualifiedName = names.get(names.size() - 2);
78              qualifiedName.setNameWhichThisQualifies(name);
79          }
80      }
81  
82  
83      @Override
84      public String toString() {
85      	StringBuilder result = new StringBuilder();
86          for (NameOccurrence occ: names) {
87              result.append(occ);
88              result.append(PMD.EOL);
89          }
90          return result.toString();
91      }
92  }