1   /***
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3   */
4   package test.net.sourceforge.pmd.symboltable;
5   
6   import net.sourceforge.pmd.PMD;
7   import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
8   import net.sourceforge.pmd.ast.ASTMethodDeclaration;
9   import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
10  import net.sourceforge.pmd.ast.SimpleNode;
11  import net.sourceforge.pmd.symboltable.ClassNameDeclaration;
12  import net.sourceforge.pmd.symboltable.ClassScope;
13  import net.sourceforge.pmd.symboltable.MethodNameDeclaration;
14  import net.sourceforge.pmd.symboltable.NameOccurrence;
15  import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
16  
17  import java.util.Iterator;
18  import java.util.List;
19  import java.util.Map;
20  
21  public class ClassScopeTest extends STBBaseTst {
22  
23      public void testEnumsClassScope() {
24          parseCode15(ENUM_SCOPE);
25      }
26  
27      // FIXME - these will break when this goes from Anonymous$1 to Foo$1
28      public void testAnonymousInnerClassName() {
29          ClassScope s = new ClassScope();
30          assertEquals("Anonymous$1", s.getClassName());
31          s = new ClassScope();
32          assertEquals("Anonymous$2", s.getClassName());
33      }
34  
35      public void testContains() {
36          ClassScope s = new ClassScope("Foo");
37          ASTVariableDeclaratorId node = new ASTVariableDeclaratorId(1);
38          node.setImage("bar");
39          s.addDeclaration(new VariableNameDeclaration(node));
40          assertTrue(s.getVariableDeclarations().keySet().iterator().hasNext());
41      }
42  
43      public void testCantContainsSuperToString() {
44          ClassScope s = new ClassScope("Foo");
45          SimpleNode node = new SimpleNode(1);
46          node.setImage("super.toString");
47          assertTrue(!s.contains(new NameOccurrence(node, node.getImage())));
48      }
49  
50      public void testContainsStaticVariablePrefixedWithClassName() {
51          ClassScope s = new ClassScope("Foo");
52          ASTVariableDeclaratorId node = new ASTVariableDeclaratorId(1);
53          node.setImage("X");
54          s.addDeclaration(new VariableNameDeclaration(node));
55  
56          SimpleNode node2 = new SimpleNode(2);
57          node2.setImage("Foo.X");
58          assertTrue(s.contains(new NameOccurrence(node2, node2.getImage())));
59      }
60  
61      public void testClassName() {
62          parseCode(CLASS_NAME);
63          ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration)acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
64          assertEquals("Foo", n.getScope().getEnclosingClassScope().getClassName());
65      }
66  
67      public void testMethodDeclarationRecorded() {
68          parseCode(METHOD_DECLARATIONS_RECORDED);
69          ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration)acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
70          ClassScope s = (ClassScope)n.getScope();
71          Map m = s.getMethodDeclarations();
72          assertEquals(1, m.size());
73          MethodNameDeclaration mnd = (MethodNameDeclaration)m.keySet().iterator().next();
74          assertEquals("bar", mnd.getImage());
75          ASTMethodDeclaration node = (ASTMethodDeclaration)mnd.getNode().jjtGetParent();
76          assertTrue(node.isPrivate());
77      }
78  
79      public void testTwoMethodsSameNameDiffArgs() {
80          // TODO this won't work with String and java.lang.String
81          parseCode(METHODS_WITH_DIFF_ARG);
82          ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration)acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
83          Map m = ((ClassScope)n.getScope()).getMethodDeclarations();
84          assertEquals(2, m.size());
85          Iterator i = m.keySet().iterator();
86          MethodNameDeclaration mnd = (MethodNameDeclaration)i.next();
87          assertEquals("bar", mnd.getImage());
88          assertEquals("bar", ((MethodNameDeclaration)i.next()).getImage());
89      }
90  
91  
92      public final void testOneParams() throws Throwable {
93          parseCode(ONE_PARAM);
94          ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration)acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
95          Map m = ((ClassScope)n.getScope()).getMethodDeclarations();
96          MethodNameDeclaration mnd = (MethodNameDeclaration)m.keySet().iterator().next();
97          assertEquals("(String)", mnd.getParameterDisplaySignature());
98      }
99  
100     public final void testTwoParams() throws Throwable {
101         parseCode(TWO_PARAMS);
102         ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration)acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
103         Map m = ((ClassScope)n.getScope()).getMethodDeclarations();
104         MethodNameDeclaration mnd = (MethodNameDeclaration)m.keySet().iterator().next();
105         assertEquals("(String,int)", mnd.getParameterDisplaySignature());
106     }
107 
108     public final void testNoParams() throws Throwable {
109         parseCode(NO_PARAMS);
110         ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration)acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
111         Map m = ((ClassScope)n.getScope()).getMethodDeclarations();
112         MethodNameDeclaration mnd = (MethodNameDeclaration)m.keySet().iterator().next();
113         assertEquals("()", mnd.getParameterDisplaySignature());
114     }
115 
116 
117     public final void testNestedClassDeclFound() throws Throwable {
118         parseCode(NESTED_CLASS_FOUND);
119         ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration)acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
120         ClassScope c = (ClassScope)n.getScope();
121         Map m = c.getClassDeclarations();
122         ClassNameDeclaration cnd = (ClassNameDeclaration)m.keySet().iterator().next();
123         assertEquals("Buz", cnd.getImage());
124     }
125 
126     public final void testbuz() throws Throwable {
127         parseCode(METH);
128         //SymbolTableViewer st = new SymbolTableViewer();
129         //acu.jjtAccept(st, null);
130     }
131 
132     public void testMethodUsageSeen() {
133         parseCode(METHOD_USAGE_SEEN);
134         ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration)acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
135         Map m = ((ClassScope)n.getScope()).getMethodDeclarations();
136         Iterator i = m.keySet().iterator();
137         MethodNameDeclaration mnd = (MethodNameDeclaration)i.next();
138         if (!mnd.getImage().equals("bar")) {
139             mnd = (MethodNameDeclaration)i.next();
140         }
141         List usages = (List)m.get(mnd);
142         assertEquals(1, usages.size());
143         assertEquals("bar", ((NameOccurrence)usages.get(0)).getImage());
144     }
145 
146     public void testMethodUsageSeenWithThis() {
147         parseCode(METHOD_USAGE_SEEN_WITH_THIS);
148         ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration)acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
149         Map m = ((ClassScope)n.getScope()).getMethodDeclarations();
150         Iterator i = m.keySet().iterator();
151         MethodNameDeclaration mnd = (MethodNameDeclaration)i.next();
152         if (!mnd.getImage().equals("bar")) {
153             mnd = (MethodNameDeclaration)i.next();
154         }
155         List usages = (List)m.get(mnd);
156         assertEquals(1, usages.size());
157         assertEquals("bar", ((NameOccurrence)usages.get(0)).getImage());
158     }
159 
160     public void testMethodUsageSeen2() {
161         parseCode(METHOD_USAGE_SEEN2);
162         ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration)acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
163         Map m = ((ClassScope)n.getScope()).getMethodDeclarations();
164         Iterator i = m.keySet().iterator();
165         MethodNameDeclaration mnd = (MethodNameDeclaration)i.next();
166         if (mnd.getNode().getBeginLine() == 2) {
167             List usages = (List)m.get(mnd);
168             System.out.println(usages.size());
169             System.out.println(mnd);
170             mnd = (MethodNameDeclaration)i.next();
171         }
172     }
173 
174     private static final String METHOD_USAGE_SEEN2 =
175     "public class Foo {" + PMD.EOL +
176     " public void baz() {" + PMD.EOL +
177     "  baz(x, y);" + PMD.EOL +
178     " }" + PMD.EOL +
179    " private void baz(int x, int y) {}" + PMD.EOL +
180     "}";
181 
182 
183     private static final String METHOD_USAGE_SEEN =
184     "public class Foo {" + PMD.EOL +
185     " private void bar() {}" + PMD.EOL +
186     " public void buz() {" + PMD.EOL +
187     "  bar();" + PMD.EOL +
188     " }" + PMD.EOL +
189     "}";
190 
191     private static final String METHOD_USAGE_SEEN_WITH_THIS =
192     "public class Foo {" + PMD.EOL +
193     " private void bar() {}" + PMD.EOL +
194     " public void buz() {" + PMD.EOL +
195     "  this.bar();" + PMD.EOL +
196     " }" + PMD.EOL +
197     "}";
198 
199 
200     private static final String METH =
201     "public class Test {" + PMD.EOL +
202     "  static { " + PMD.EOL +
203     "   int y; " + PMD.EOL +
204     "  } " + PMD.EOL +
205     "  void bar(int x) {} " + PMD.EOL +
206     "  void baz(int x) {} " + PMD.EOL +
207     "}";
208 
209     private static final String NESTED_CLASS_FOUND =
210     "public class Test {" + PMD.EOL +
211     "  private class Buz {} " + PMD.EOL +
212     "}";
213 
214     private static final String ONE_PARAM =
215     "public class Test {" + PMD.EOL +
216     "  void bar(String x) {" + PMD.EOL +
217     "  }" + PMD.EOL +
218     "}";
219 
220     private static final String TWO_PARAMS =
221     "public class Test {" + PMD.EOL +
222     "  void bar(String x, int y) {" + PMD.EOL +
223     "  }" + PMD.EOL +
224     "}";
225 
226     private static final String NO_PARAMS =
227     "public class Test {" + PMD.EOL +
228     "  void bar() {" + PMD.EOL +
229     "  }" + PMD.EOL +
230     "}";
231 
232 
233     private static final String CLASS_NAME =
234     "public class Foo {}";
235 
236     private static final String METHOD_DECLARATIONS_RECORDED =
237     "public class Foo {" + PMD.EOL +
238     " private void bar() {}" + PMD.EOL +
239     "}";
240 
241     private static final String METHODS_WITH_DIFF_ARG =
242     "public class Foo {" + PMD.EOL +
243     " private void bar(String x) {}" + PMD.EOL +
244     " private void bar() {}" + PMD.EOL +
245     "}";
246 
247     private static final String ENUM_SCOPE =
248     "public enum Foo {" + PMD.EOL +
249     " HEAP(\"foo\");" + PMD.EOL +
250     " private final String fuz;" + PMD.EOL +
251     " public String getFuz() {" + PMD.EOL +
252     "  return fuz;" + PMD.EOL +
253     " }" + PMD.EOL +
254     "}";
255 
256 
257 }