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.List;
7
8 import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
9 import net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter;
10 import net.sourceforge.pmd.lang.symboltable.NameDeclaration;
11 import net.sourceforge.pmd.lang.symboltable.Scope;
12
13 public class OccurrenceFinder extends JavaParserVisitorAdapter {
14
15 public Object visit(ASTPrimaryExpression node, Object data) {
16 NameFinder nameFinder = new NameFinder(node);
17
18 // Maybe do some sort of State pattern thingy for when NameDeclaration
19 // is null/not null?
20 NameDeclaration decl = null;
21
22 List<JavaNameOccurrence> names = nameFinder.getNames();
23 for (JavaNameOccurrence occ : names) {
24 Search search = new Search(occ);
25 if (decl == null) {
26 // doing the first name lookup
27 search.execute();
28 decl = search.getResult();
29 if (decl == null) {
30 // we can't find it, so just give up
31 // when we decide to do full symbol resolution
32 // force this to either find a symbol or throw a
33 // SymbolNotFoundException
34 break;
35 }
36 } else {
37 // now we've got a scope we're starting with, so work from there
38 Scope startingScope = decl.getScope();
39 // in case the previous found declaration is a class reference
40 // for a class inside the same source file
41 // we need to search this class
42 // e.g. the list of name occurrence could come from
43 // outerClassRef.member. See also bug #1302
44 if (decl instanceof VariableNameDeclaration) {
45 String typeImage = ((VariableNameDeclaration) decl).getTypeImage();
46 ClassNameDeclaration clazzDeclaration = startingScope.getEnclosingScope(SourceFileScope.class)
47 .findClassNameDeclaration(typeImage);
48 if (clazzDeclaration != null) {
49 startingScope = clazzDeclaration.getScope();
50 }
51 }
52 search.execute(startingScope);
53 decl = search.getResult();
54
55 if (decl == null) {
56 // nothing found
57 // This seems to be a lack of type resolution here.
58 // Theoretically we have the previous declaration node and
59 // know from there the Type of
60 // the variable. The current occurrence (occ) should then be
61 // found in the declaration of
62 // this type. The type however may or may not be known to
63 // PMD (see aux classpath).
64
65 // we can't find it, so just give up
66 // when we decide to do full symbol resolution
67 // force this to either find a symbol or throw a
68 // SymbolNotFoundException
69 break;
70 }
71 }
72 }
73 return super.visit(node, data);
74 }
75
76 }