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