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.List;
7   import java.util.logging.Level;
8   import java.util.logging.Logger;
9   
10  import net.sourceforge.pmd.lang.plsql.ast.ASTPrimaryExpression;
11  import net.sourceforge.pmd.lang.plsql.ast.PLSQLParserVisitorAdapter;
12  import net.sourceforge.pmd.lang.symboltable.NameDeclaration;
13  import net.sourceforge.pmd.lang.symboltable.Scope;
14  
15  public class OccurrenceFinder extends PLSQLParserVisitorAdapter {
16      private final static Logger LOGGER = Logger.getLogger(OccurrenceFinder.class.getName()); 
17  
18      public Object visit(ASTPrimaryExpression node, Object data) {
19          NameFinder nameFinder = new NameFinder(node);
20  
21          // Maybe do some sort of State pattern thingy for when NameDeclaration
22          // is null/not null?
23          NameDeclaration decl = null;
24  
25          List<PLSQLNameOccurrence> names = nameFinder.getNames();
26          for (PLSQLNameOccurrence occ: names) {
27              Search search = new Search(occ);
28              if (decl == null) {
29                  // doing the first name lookup
30                  search.execute();
31                  decl = search.getResult();
32                  if (decl == null) {
33                      // we can't find it, so just give up
34                      // when we decide to do full symbol resolution
35                      // force this to either find a symbol or throw a SymbolNotFoundException
36                      break;
37                  }
38              } else {
39                  // now we've got a scope we're starting with, so work from there
40                  Scope scope = decl.getScope();
41                  if (null == scope) 
42                  {
43                      if (LOGGER.isLoggable(Level.FINEST)) {
44                    LOGGER.finest("NameOccurrence has no Scope:" 
45                                        + decl.getClass().getCanonicalName() 
46                                        +"=>"+decl.getImage()
47                                      );
48                      }
49                    break;
50                  }
51                  search.execute(scope);
52                  decl = search.getResult();
53  
54                  if (decl == null) {
55                      // nothing found
56                      // This seems to be a lack of type resolution here.
57                      // Theoretically we have the previous declaration node and know from there the Type of
58                      // the variable. The current occurrence (occ) should then be found in the declaration of
59                      // this type. The type however may or may not be known to PMD (see aux classpath).
60  
61                      // we can't find it, so just give up
62                      // when we decide to do full symbol resolution
63                      // force this to either find a symbol or throw a SymbolNotFoundException
64                      break;
65                  }
66              }
67          }
68          return super.visit(node, data);
69      }
70  
71  }