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 }