View Javadoc

1   /***
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3   */
4   package net.sourceforge.pmd.symboltable;
5   
6   import net.sourceforge.pmd.util.Applier;
7   
8   import java.util.ArrayList;
9   import java.util.List;
10  
11  public class ClassScope extends AbstractScope {
12  
13      // FIXME - this breaks give sufficiently nested code
14      private static int anonymousInnerClassCounter = 1;
15      private String className;
16  
17      public ClassScope(String className) {
18          this.className = className;
19          anonymousInnerClassCounter = 1;
20      }
21  
22      /***
23       * This is only for anonymous inner classes
24       *
25       * FIXME - should have name like Foo$1, not Anonymous$1
26       * to get this working right, the parent scope needs
27       * to be passed in when instantiating a ClassScope
28       */
29      public ClassScope() {
30          //this.className = getParent().getEnclosingClassScope().getClassName() + "$" + String.valueOf(anonymousInnerClassCounter);
31          this.className = "Anonymous$" + String.valueOf(anonymousInnerClassCounter);
32          anonymousInnerClassCounter++;
33      }
34  
35      public ClassScope getEnclosingClassScope() {
36          return this;
37      }
38  
39      public String getClassName() {
40          return this.className;
41      }
42  
43      public void addDeclaration(MethodNameDeclaration decl) {
44          methodNames.put(decl, new ArrayList());
45      }
46  
47      protected NameDeclaration findVariableHere(NameOccurrence occurrence) {
48          if (occurrence.isThisOrSuper() || occurrence.getImage().equals(className)) {
49              if (variableNames.isEmpty()) {
50                  // this could happen if you do this:
51                  // public class Foo {
52                  //  private String x = super.toString();
53                  // }
54                  return null;
55              }
56              // return any name declaration, since all we really want is to get the scope
57              // for example, if there's a
58              // public class Foo {
59              //  private static final int X = 2;
60              //  private int y = Foo.X;
61              // }
62              // we'll look up Foo just to get a handle to the class scope
63              // and then we'll look up X.
64              return (NameDeclaration) variableNames.keySet().iterator().next();
65          }
66  
67          List images = new ArrayList();
68          images.add(occurrence.getImage());
69          if (occurrence.getImage().startsWith(className)) {
70              images.add(clipClassName(occurrence.getImage()));
71          }
72          ImageFinderFunction finder = new ImageFinderFunction(images);
73          Applier.apply(finder, variableNames.keySet().iterator());
74          return finder.getDecl();
75      }
76  
77      public String toString() {
78          return "ClassScope:" + className + ":" + super.glomNames();
79      }
80  
81      private String clipClassName(String in) {
82          int firstDot = in.indexOf('.');
83          return in.substring(firstDot + 1);
84      }
85  }