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