1
2
3
4 package net.sourceforge.pmd.symboltable;
5
6 import static org.junit.Assert.assertEquals;
7 import static org.junit.Assert.assertFalse;
8 import static org.junit.Assert.assertTrue;
9 import static org.junit.Assert.fail;
10
11 import java.util.Iterator;
12 import java.util.List;
13 import java.util.Map;
14
15 import net.sourceforge.pmd.PMD;
16 import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
17 import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
18 import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
19 import net.sourceforge.pmd.lang.java.ast.DummyJavaNode;
20 import net.sourceforge.pmd.lang.java.ast.JavaNode;
21 import net.sourceforge.pmd.lang.java.symboltable.ClassNameDeclaration;
22 import net.sourceforge.pmd.lang.java.symboltable.ClassScope;
23 import net.sourceforge.pmd.lang.java.symboltable.MethodNameDeclaration;
24 import net.sourceforge.pmd.lang.java.symboltable.JavaNameOccurrence;
25 import net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration;
26 import net.sourceforge.pmd.lang.symboltable.NameDeclaration;
27 import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
28
29 import org.junit.Test;
30 public class ClassScopeTest extends STBBaseTst {
31
32 @Test
33 public void testEnumsClassScope() {
34 parseCode15(ENUM_SCOPE);
35 }
36
37
38 @Test
39 public void testAnonymousInnerClassName() {
40 ClassScope s = new ClassScope("Foo");
41 s = new ClassScope();
42 assertEquals("Anonymous$1", s.getClassName());
43 s = new ClassScope();
44 assertEquals("Anonymous$2", s.getClassName());
45 }
46
47 @Test
48 public void testContains() {
49 ClassScope s = new ClassScope("Foo");
50 ASTVariableDeclaratorId node = new ASTVariableDeclaratorId(1);
51 node.setImage("bar");
52 s.addDeclaration(new VariableNameDeclaration(node));
53 assertTrue(s.getDeclarations().keySet().iterator().hasNext());
54 }
55
56 @Test
57 public void testCantContainsSuperToString() {
58 ClassScope s = new ClassScope("Foo");
59 JavaNode node = new DummyJavaNode(1);
60 node.setImage("super.toString");
61 assertFalse(s.contains(new JavaNameOccurrence(node, node.getImage())));
62 }
63
64 @Test
65 public void testContainsStaticVariablePrefixedWithClassName() {
66 ClassScope s = new ClassScope("Foo");
67 ASTVariableDeclaratorId node = new ASTVariableDeclaratorId(1);
68 node.setImage("X");
69 s.addDeclaration(new VariableNameDeclaration(node));
70
71 JavaNode node2 = new DummyJavaNode(2);
72 node2.setImage("Foo.X");
73 assertTrue(s.contains(new JavaNameOccurrence(node2, node2.getImage())));
74 }
75
76 @Test
77 public void testClassName() {
78 parseCode(CLASS_NAME);
79 ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0);
80 assertEquals("Foo", n.getScope().getEnclosingScope(ClassScope.class).getClassName());
81 }
82
83 @Test
84 public void testMethodDeclarationRecorded() {
85 parseCode(METHOD_DECLARATIONS_RECORDED);
86 ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0);
87 ClassScope s = (ClassScope) n.getScope();
88 Map m = s.getDeclarations();
89 assertEquals(1, m.size());
90 MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next();
91 assertEquals("bar", mnd.getImage());
92 ASTMethodDeclaration node = (ASTMethodDeclaration) mnd.getNode().jjtGetParent();
93 assertTrue(node.isPrivate());
94 }
95
96 @Test
97 public void testTwoMethodsSameNameDiffArgs() {
98
99 parseCode(METHODS_WITH_DIFF_ARG);
100 ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0);
101 Map m = ((ClassScope) n.getScope()).getDeclarations();
102 assertEquals(2, m.size());
103 Iterator i = m.keySet().iterator();
104 MethodNameDeclaration mnd = (MethodNameDeclaration) i.next();
105 assertEquals("bar", mnd.getImage());
106 assertEquals("bar", ((MethodNameDeclaration) i.next()).getImage());
107 }
108
109
110 @Test
111 public final void testOneParam() throws Throwable {
112 parseCode(ONE_PARAM);
113 ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0);
114 Map m = ((ClassScope) n.getScope()).getDeclarations();
115 MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next();
116 assertEquals("(String)", mnd.getParameterDisplaySignature());
117 }
118
119 @Test
120 public final void testTwoParams() throws Throwable {
121 parseCode(TWO_PARAMS);
122 ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0);
123 Map m = ((ClassScope) n.getScope()).getDeclarations();
124 MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next();
125 assertEquals("(String,int)", mnd.getParameterDisplaySignature());
126 }
127
128 @Test
129 public final void testNoParams() throws Throwable {
130 parseCode(NO_PARAMS);
131 ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0);
132 Map m = ((ClassScope) n.getScope()).getDeclarations();
133 MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next();
134 assertEquals("()", mnd.getParameterDisplaySignature());
135 }
136
137 @Test
138 public final void testOneParamVararg() throws Throwable {
139 parseCode15(ONE_PARAM_VARARG);
140 ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0);
141 Map m = ((ClassScope) n.getScope()).getDeclarations();
142 MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next();
143 assertEquals("(String...)", mnd.getParameterDisplaySignature());
144 }
145
146 @Test
147 public final void testTwoParamsVararg() throws Throwable {
148 parseCode15(TWO_PARAMS_VARARG);
149 ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0);
150 Map m = ((ClassScope) n.getScope()).getDeclarations();
151 MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next();
152 assertEquals("(String,String...)", mnd.getParameterDisplaySignature());
153 }
154
155
156 @Test
157 public final void testNestedClassDeclFound() throws Throwable {
158 parseCode(NESTED_CLASS_FOUND);
159 ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0);
160 ClassScope c = (ClassScope) n.getScope();
161 Map m = c.getDeclarations();
162 ClassNameDeclaration cnd = (ClassNameDeclaration) m.keySet().iterator().next();
163 assertEquals("Buz", cnd.getImage());
164 }
165
166 @Test
167 public final void testbuz() throws Throwable {
168 parseCode(METH);
169
170
171 }
172
173 @Test
174 public void testMethodUsageSeen() {
175 parseCode(METHOD_USAGE_SEEN);
176 ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0);
177 Map m = ((ClassScope) n.getScope()).getDeclarations();
178 Iterator i = m.entrySet().iterator();
179 MethodNameDeclaration mnd;
180 Map.Entry entry;
181
182 do {
183 entry = (Map.Entry) i.next();
184 mnd = (MethodNameDeclaration) entry.getKey();
185 } while (!mnd.getImage().equals("bar"));
186
187 List usages = (List) entry.getValue();
188 assertEquals(1, usages.size());
189 assertEquals("bar", ((JavaNameOccurrence) usages.get(0)).getImage());
190 }
191
192 @Test
193 public void testMethodUsageSeenWithThis() {
194 parseCode(METHOD_USAGE_SEEN_WITH_THIS);
195 ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0);
196 Map m = ((ClassScope) n.getScope()).getDeclarations();
197 Iterator i = m.entrySet().iterator();
198 MethodNameDeclaration mnd;
199 Map.Entry entry;
200
201 do {
202 entry = (Map.Entry) i.next();
203 mnd = (MethodNameDeclaration) entry.getKey();
204 } while (!mnd.getImage().equals("bar"));
205
206 List usages = (List) entry.getValue();
207 assertEquals(1, usages.size());
208 assertEquals("bar", ((JavaNameOccurrence) usages.get(0)).getImage());
209 }
210
211 @Test
212 public void testMethodUsageSeen2() {
213 parseCode(METHOD_USAGE_SEEN2);
214 ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0);
215
216 Map<NameDeclaration, List<NameOccurrence>> m = ((ClassScope) n.getScope()).getDeclarations();
217
218 assertEquals(2, m.size());
219
220 for (Map.Entry<NameDeclaration, List<NameOccurrence>> entry : m.entrySet()) {
221 assertEquals("baz", entry.getKey().getImage());
222 if (entry.getKey().getNode().getBeginLine() == 2) {
223
224 assertEquals(0, entry.getValue().size());
225 } else if (entry.getKey().getNode().getBeginLine() == 5) {
226
227 assertEquals(1, entry.getValue().size());
228
229 assertEquals(3, entry.getValue().get(0).getLocation().getBeginLine());
230 } else {
231 fail("unexpected name declaration");
232 }
233 }
234 }
235
236
237
238
239 @Test
240 public void testNestedClassFieldAndParameter() {
241 parseCode(NESTED_CLASS_FIELD_AND_PARAM);
242 ASTMethodDeclaration node = acu.getFirstDescendantOfType(ASTMethodDeclaration.class);
243 Map<NameDeclaration, List<NameOccurrence>> vd = node.getScope().getDeclarations();
244 assertEquals(1, vd.size());
245
246 for (Map.Entry<NameDeclaration, List<NameOccurrence>> entry : vd.entrySet()) {
247 assertEquals("field", entry.getKey().getImage());
248
249 List<NameOccurrence> occurrences = entry.getValue();
250 assertEquals(2, occurrences.size());
251 NameOccurrence no1 = occurrences.get(0);
252 assertEquals(8, no1.getLocation().getBeginLine());
253 NameOccurrence no2 = occurrences.get(1);
254 assertEquals(9, no2.getLocation().getBeginLine());
255 }
256
257 }
258
259 private static final String NESTED_CLASS_FIELD_AND_PARAM =
260 "public class Foo {" + PMD.EOL +
261 " class Test {" + PMD.EOL +
262 " public String field;" + PMD.EOL +
263 " public Test t;" + PMD.EOL +
264 " }" + PMD.EOL +
265 " public void foo(String field) {" + PMD.EOL +
266 " Test t = new Test();" + PMD.EOL +
267 " t.field = field;" + PMD.EOL +
268 " t.t.field = field;" + PMD.EOL +
269 " }" + PMD.EOL +
270 "}";
271
272 private static final String METHOD_USAGE_SEEN2 =
273 "public class Foo {" + PMD.EOL +
274 " public void baz() {" + PMD.EOL +
275 " baz(x, y);" + PMD.EOL +
276 " }" + PMD.EOL +
277 " private void baz(int x, int y) {}" + PMD.EOL +
278 "}";
279
280
281 private static final String METHOD_USAGE_SEEN =
282 "public class Foo {" + PMD.EOL +
283 " private void bar() {}" + PMD.EOL +
284 " public void buz() {" + PMD.EOL +
285 " bar();" + PMD.EOL +
286 " }" + PMD.EOL +
287 "}";
288
289 private static final String METHOD_USAGE_SEEN_WITH_THIS =
290 "public class Foo {" + PMD.EOL +
291 " private void bar() {}" + PMD.EOL +
292 " public void buz() {" + PMD.EOL +
293 " this.bar();" + PMD.EOL +
294 " }" + PMD.EOL +
295 "}";
296
297
298 private static final String METH =
299 "public class Test {" + PMD.EOL +
300 " static { " + PMD.EOL +
301 " int y; " + PMD.EOL +
302 " } " + PMD.EOL +
303 " void bar(int x) {} " + PMD.EOL +
304 " void baz(int x) {} " + PMD.EOL +
305 "}";
306
307 private static final String NESTED_CLASS_FOUND =
308 "public class Test {" + PMD.EOL +
309 " private class Buz {} " + PMD.EOL +
310 "}";
311
312 private static final String ONE_PARAM =
313 "public class Test {" + PMD.EOL +
314 " void bar(String x) {" + PMD.EOL +
315 " }" + PMD.EOL +
316 "}";
317
318 private static final String TWO_PARAMS =
319 "public class Test {" + PMD.EOL +
320 " void bar(String x, int y) {" + PMD.EOL +
321 " }" + PMD.EOL +
322 "}";
323
324 private static final String NO_PARAMS =
325 "public class Test {" + PMD.EOL +
326 " void bar() {" + PMD.EOL +
327 " }" + PMD.EOL +
328 "}";
329
330 private static final String ONE_PARAM_VARARG =
331 "public class Test {" + PMD.EOL +
332 " void bar(String... s) {" + PMD.EOL +
333 " }" + PMD.EOL +
334 "}";
335
336 private static final String TWO_PARAMS_VARARG =
337 "public class Test {" + PMD.EOL +
338 " void bar(String s1, String... s2) {" + PMD.EOL +
339 " }" + PMD.EOL +
340 "}";
341
342
343 private static final String CLASS_NAME =
344 "public class Foo {}";
345
346 private static final String METHOD_DECLARATIONS_RECORDED =
347 "public class Foo {" + PMD.EOL +
348 " private void bar() {}" + PMD.EOL +
349 "}";
350
351 private static final String METHODS_WITH_DIFF_ARG =
352 "public class Foo {" + PMD.EOL +
353 " private void bar(String x) {}" + PMD.EOL +
354 " private void bar() {}" + PMD.EOL +
355 "}";
356
357 private static final String ENUM_SCOPE =
358 "public enum Foo {" + PMD.EOL +
359 " HEAP(\"foo\");" + PMD.EOL +
360 " private final String fuz;" + PMD.EOL +
361 " public String getFuz() {" + PMD.EOL +
362 " return fuz;" + PMD.EOL +
363 " }" + PMD.EOL +
364 "}";
365
366 public static junit.framework.Test suite() {
367 return new junit.framework.JUnit4TestAdapter(ClassScopeTest.class);
368 }
369 }