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