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