View Javadoc
1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.lang.plsql.symboltable;
5   
6   import java.util.HashSet;
7   import java.util.Set;
8   import java.util.logging.Level;
9   import java.util.logging.Logger;
10  
11  import net.sourceforge.pmd.lang.symboltable.NameDeclaration;
12  import net.sourceforge.pmd.lang.symboltable.Scope;
13  
14  public class Search {
15      private final static Logger LOGGER = Logger.getLogger(Search.class.getName()); 
16  
17      private PLSQLNameOccurrence occ;
18      private Set<NameDeclaration> declarations = new HashSet<>();
19  
20      public Search(PLSQLNameOccurrence occ) {
21          if (LOGGER.isLoggable(Level.FINEST)) {
22              LOGGER.finest("new search for " + (occ.isMethodOrConstructorInvocation() ? "method" : "variable") + " " + occ);
23          }
24          this.occ = occ;
25      }
26  
27      public void execute() {
28          Set<NameDeclaration> found = searchUpward(occ, occ.getLocation().getScope());
29          if (LOGGER.isLoggable(Level.FINEST)) {
30              LOGGER.finest("found " + found);
31          }
32          declarations.addAll(found);
33      }
34  
35      public void execute(Scope startingScope) {
36          Set<NameDeclaration> found = searchUpward(occ, startingScope);
37          if (LOGGER.isLoggable(Level.FINEST)) {
38              LOGGER.finest("found " + found);
39          }
40          declarations.addAll(found);
41      }
42  
43      public Set<NameDeclaration> getResult() {
44          return declarations;
45      }
46  
47      private Set<NameDeclaration> searchUpward(PLSQLNameOccurrence nameOccurrence, Scope scope) {
48          if (LOGGER.isLoggable(Level.FINEST)) {
49              LOGGER.finest("checking scope " + scope + " for name occurrence " + nameOccurrence);
50          }
51          if (!scope.contains(nameOccurrence) && scope.getParent() != null) {
52              if (LOGGER.isLoggable(Level.FINEST)) {
53                  LOGGER.finest("moving up fm " + scope + " to " + scope.getParent());
54              }
55              return searchUpward(nameOccurrence, scope.getParent());
56          }
57          if (scope.contains(nameOccurrence)) {
58              if (LOGGER.isLoggable(Level.FINEST)) {
59                  LOGGER.finest("found it!");
60              }
61              return scope.addNameOccurrence(nameOccurrence);
62          }
63          return new HashSet<>();
64      }
65  }