1
2
3
4 package net.sourceforge.pmd.lang.java.ast;
5
6 import static org.junit.Assert.assertEquals;
7 import static org.junit.Assert.assertFalse;
8 import static org.junit.Assert.assertNotNull;
9 import static org.junit.Assert.assertNull;
10 import static org.junit.Assert.assertSame;
11 import static org.junit.Assert.assertTrue;
12
13 import java.util.ArrayList;
14 import java.util.Iterator;
15 import java.util.List;
16 import java.util.Set;
17
18 import net.sourceforge.pmd.PMD;
19 import net.sourceforge.pmd.lang.ast.Node;
20 import net.sourceforge.pmd.lang.java.ParserTst;
21
22 import org.junit.Ignore;
23 import org.junit.Test;
24
25
26 public class SimpleNodeTest extends ParserTst {
27
28 @Test
29 public void testMethodDiffLines() throws Throwable {
30 Set<ASTMethodDeclaration> methods = getNodes(ASTMethodDeclaration.class, METHOD_DIFF_LINES);
31 verifyNode(methods.iterator().next(), 2, 9, 4, 2);
32 }
33
34 @Test
35 public void testMethodSameLine() throws Throwable {
36 Set<ASTMethodDeclaration> methods = getNodes(ASTMethodDeclaration.class, METHOD_SAME_LINE);
37 verifyNode(methods.iterator().next(), 2, 9, 2, 21);
38 }
39
40 @Test
41 public void testNoLookahead() throws Throwable {
42 String code = NO_LOOKAHEAD;
43 Set<ASTClassOrInterfaceDeclaration> uCD = getNodes(ASTClassOrInterfaceDeclaration.class, code);
44 verifyNode(uCD.iterator().next(), 1, 8, 1, 20);
45 }
46
47 @Test
48 public void testHasExplicitExtends() throws Throwable {
49 String code = HAS_EXPLICIT_EXTENDS;
50 ASTClassOrInterfaceDeclaration ucd = getNodes(ASTClassOrInterfaceDeclaration.class, code).iterator().next();
51 assertTrue(ucd.jjtGetChild(0) instanceof ASTExtendsList);
52 }
53
54 @Test
55 public void testNoExplicitExtends() throws Throwable {
56 String code = NO_EXPLICIT_EXTENDS;
57 ASTClassOrInterfaceDeclaration ucd = getNodes(ASTClassOrInterfaceDeclaration.class, code).iterator().next();
58 assertFalse(ucd.jjtGetChild(0) instanceof ASTExtendsList);
59 }
60
61 @Test
62 public void testHasExplicitImplements() throws Throwable {
63 String code = HAS_EXPLICIT_IMPLEMENTS;
64 ASTClassOrInterfaceDeclaration ucd = getNodes(ASTClassOrInterfaceDeclaration.class, code).iterator().next();
65 assertTrue(ucd.jjtGetChild(0) instanceof ASTImplementsList);
66 }
67
68 @Test
69 public void testNoExplicitImplements() throws Throwable {
70 String code = NO_EXPLICIT_IMPLEMENTS;
71 ASTClassOrInterfaceDeclaration ucd = getNodes(ASTClassOrInterfaceDeclaration.class, code).iterator().next();
72 assertFalse(ucd.jjtGetChild(0) instanceof ASTImplementsList);
73 }
74
75 @Test
76 public void testColumnsOnQualifiedName() throws Throwable {
77 Set<ASTName> name = getNodes(ASTName.class, QUALIFIED_NAME);
78 Iterator<ASTName> i = name.iterator();
79 while (i.hasNext()) {
80 Node node = i.next();
81 if (node.getImage().equals("java.io.File")) {
82 verifyNode(node, 1, 8, 1, 19);
83 }
84 }
85 }
86
87 @Test
88 public void testLineNumbersForNameSplitOverTwoLines() throws Throwable {
89 Set<ASTName> name = getNodes(ASTName.class, BROKEN_LINE_IN_NAME);
90 Iterator<ASTName> i = name.iterator();
91 while (i.hasNext()) {
92 Node node = i.next();
93 if (node.getImage().equals("java.io.File")) {
94 verifyNode(node, 1, 8, 2, 4);
95 }
96 if (node.getImage().equals("Foo")) {
97 verifyNode(node, 2, 15, 2, 18);
98 }
99 }
100 }
101
102 @Test
103 public void testLineNumbersAreSetOnAllSiblings() throws Throwable {
104 for (ASTBlock b: getNodes(ASTBlock.class, LINE_NUMBERS_ON_SIBLINGS)) {
105 assertTrue(b.getBeginLine() > 0);
106 }
107 for (ASTVariableInitializer b: getNodes(ASTVariableInitializer.class, LINE_NUMBERS_ON_SIBLINGS)) {
108 assertTrue(b.getBeginLine() > 0);
109 }
110 for (ASTExpression b: getNodes(ASTExpression.class, LINE_NUMBERS_ON_SIBLINGS)) {
111 assertTrue(b.getBeginLine() > 0);
112 }
113 }
114
115 @Test
116 public void testFindDescendantsOfType() {
117 ASTBlock block = new ASTBlock(2);
118 block.jjtAddChild(new ASTReturnStatement(1), 0);
119 assertEquals(1, block.findDescendantsOfType(ASTReturnStatement.class).size());
120 }
121
122 @Test
123 public void testFindDescendantsOfTypeMultiple() {
124 ASTBlock block = new ASTBlock(1);
125 block.jjtAddChild(new ASTBlockStatement(2), 0);
126 block.jjtAddChild(new ASTBlockStatement(3), 1);
127 List<ASTBlockStatement> nodes = block.findDescendantsOfType(ASTBlockStatement.class);
128 assertEquals(2, nodes.size());
129 }
130
131 @Test
132 public void testFindDescendantsOfTypeRecurse() {
133 ASTBlock block = new ASTBlock(1);
134 ASTBlock childBlock = new ASTBlock(2);
135 block.jjtAddChild(childBlock, 0);
136 childBlock.jjtAddChild(new ASTMethodDeclaration(3), 0);
137 List<ASTMethodDeclaration> nodes = block.findDescendantsOfType(ASTMethodDeclaration.class);
138 assertEquals(1, nodes.size());
139 }
140
141 @Test
142 public void testGetFirstChild() {
143 ASTBlock block = new ASTBlock(1);
144 ASTStatement x = new ASTStatement(2);
145 block.jjtAddChild(x, 0);
146 block.jjtAddChild(new ASTStatement(3), 1);
147
148 Node n = block.getFirstDescendantOfType(ASTStatement.class);
149 assertNotNull(n);
150 assertTrue(n instanceof ASTStatement);
151 assertEquals(x, n);
152 }
153
154 @Test
155 public void testGetFirstChildNested() {
156 ASTBlock block = new ASTBlock(1);
157 ASTStatement x = new ASTStatement(2);
158 ASTAssignmentOperator x1 = new ASTAssignmentOperator(4);
159 x.jjtAddChild(x1, 0);
160 block.jjtAddChild(x, 0);
161 block.jjtAddChild(new ASTStatement(3), 1);
162
163 Node n = block.getFirstDescendantOfType(ASTAssignmentOperator.class);
164 assertNotNull(n);
165 assertTrue(n instanceof ASTAssignmentOperator);
166 assertEquals(x1, n);
167 }
168
169 @Test
170 public void testGetFirstChildNestedDeeper() {
171 ASTBlock block = new ASTBlock(1);
172 ASTStatement x = new ASTStatement(2);
173 ASTAssignmentOperator x1 = new ASTAssignmentOperator(4);
174 ASTName x2 = new ASTName(5);
175
176 x.jjtAddChild(x1, 0);
177 x1.jjtAddChild(x2, 0);
178 block.jjtAddChild(x, 0);
179 block.jjtAddChild(new ASTStatement(3), 1);
180
181 Node n = block.getFirstDescendantOfType(ASTName.class);
182 assertNotNull(n);
183 assertTrue(n instanceof ASTName);
184 assertEquals(x2, n);
185 }
186
187 @Test
188 public void testParentMethods() throws Throwable {
189 ASTCompilationUnit u = parseJava14(TEST1);
190
191 ASTMethodDeclarator d = u.getFirstDescendantOfType(ASTMethodDeclarator.class);
192 assertSame("getFirstParentOfType ASTMethodDeclaration", d.jjtGetParent(), d.getFirstParentOfType(ASTMethodDeclaration.class));
193 assertNull("getFirstParentOfType ASTName", d.getFirstParentOfType(ASTName.class));
194
195 assertSame("getNthParent 1", d.jjtGetParent(), d.getNthParent(1));
196 assertSame("getNthParent 2", d.jjtGetParent().jjtGetParent(), d.getNthParent(2));
197 assertSame("getNthParent 6", u, d.getNthParent(6));
198 assertNull("getNthParent 7", d.getNthParent(7));
199 assertNull("getNthParent 8", d.getNthParent(8));
200 }
201
202 private static final String TEST1 =
203 "public class Test {" + PMD.EOL +
204 " void bar(String s) {" + PMD.EOL +
205 " s = s.toLowerCase();" + PMD.EOL +
206 " }" + PMD.EOL +
207 "}";
208
209 @Ignore
210 @Test
211 public void testContainsNoInner() throws Throwable {
212 ASTCompilationUnit c = getNodes(ASTCompilationUnit.class, CONTAINS_NO_INNER).iterator().next();
213 List<ASTFieldDeclaration> res = new ArrayList<ASTFieldDeclaration>();
214 c.findDescendantsOfType(ASTFieldDeclaration.class, res, false);
215 assertTrue(res.isEmpty());
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236 }
237
238 @Test
239 public void testContainsNoInnerWithAnonInner() throws Throwable {
240 ASTCompilationUnit c = getNodes(ASTCompilationUnit.class, CONTAINS_NO_INNER_WITH_ANON_INNER).iterator().next();
241 List<ASTFieldDeclaration> res = new ArrayList<ASTFieldDeclaration>();
242 c.findDescendantsOfType(ASTFieldDeclaration.class, res, false);
243 assertTrue(res.isEmpty());
244 }
245
246 @Test
247 public void testContainsChildOfType() throws Throwable {
248 ASTClassOrInterfaceDeclaration c = getNodes(ASTClassOrInterfaceDeclaration.class, CONTAINS_CHILDREN_OF_TYPE).iterator().next();
249 assertTrue(c.hasDescendantOfType(ASTFieldDeclaration.class));
250 }
251
252 @Test
253 public void testXPathNodeSelect() throws Throwable {
254 ASTClassOrInterfaceDeclaration c = getNodes(ASTClassOrInterfaceDeclaration.class, TEST_XPATH).iterator().next();
255 List nodes = c.findChildNodesWithXPath("//FieldDeclaration");
256 assertEquals(2, nodes.size());
257 assertTrue(nodes.get(0) instanceof ASTFieldDeclaration);
258
259 assertTrue(c.hasDescendantMatchingXPath("//FieldDeclaration"));
260 assertFalse(c.hasDescendantMatchingXPath("//MethodDeclaration"));
261 }
262
263 @Test
264 public void testUserData() throws Throwable {
265 ASTClassOrInterfaceDeclaration c = getNodes(ASTClassOrInterfaceDeclaration.class, HAS_EXPLICIT_EXTENDS).iterator().next();
266 assertNull(c.getUserData());
267 c.setUserData("foo");
268 assertEquals("foo", c.getUserData());
269 c.setUserData(null);
270 assertNull(c.getUserData());
271 }
272
273 private void verifyNode(Node node, int beginLine, int beginCol, int endLine, int endCol) {
274 assertEquals("Unexpected beginning line: ", beginLine, node.getBeginLine());
275 assertEquals("Unexpected beginning column: ", beginCol, node.getBeginColumn());
276 assertEquals("Unexpected ending line:", endLine, node.getEndLine());
277 assertEquals("Unexpected ending column:", endCol, node.getEndColumn());
278 }
279
280 private static final String HAS_EXPLICIT_EXTENDS =
281 "public class Test extends Foo {}";
282
283 private static final String NO_EXPLICIT_EXTENDS =
284 "public class Test {}";
285
286 private static final String HAS_EXPLICIT_IMPLEMENTS =
287 "public class Test implements Foo {}";
288
289 private static final String NO_EXPLICIT_IMPLEMENTS =
290 "public class Test {}";
291
292 private static final String METHOD_SAME_LINE =
293 "public class Test {" + PMD.EOL +
294 " public void foo() {}" + PMD.EOL +
295 "}";
296
297 private static final String QUALIFIED_NAME =
298 "import java.io.File;" + PMD.EOL +
299 "public class Foo{}";
300
301 private static final String BROKEN_LINE_IN_NAME =
302 "import java.io." + PMD.EOL +
303 "File;" + PMD.EOL +
304 "public class Foo{}";
305
306 private static final String LINE_NUMBERS_ON_SIBLINGS =
307 "public class Foo {" + PMD.EOL +
308 " void bar() {" + PMD.EOL +
309 " try {" + PMD.EOL +
310 " } catch (Exception1 e) {" + PMD.EOL +
311 " int x =2;" + PMD.EOL +
312 " }" + PMD.EOL +
313 " if (x != null) {}" + PMD.EOL +
314 " }" + PMD.EOL +
315 "}";
316
317 private static final String NO_LOOKAHEAD = "public class Foo { }";
318
319 private static final String METHOD_DIFF_LINES =
320 "public class Test {" + PMD.EOL +
321 " public void foo() {" + PMD.EOL +
322 " int x;" + PMD.EOL +
323 " }" + PMD.EOL +
324 "}";
325
326 private static final String CONTAINS_CHILDREN_OF_TYPE =
327 "public class Test {" + PMD.EOL +
328 " int x;" + PMD.EOL +
329 "}";
330
331 private static final String CONTAINS_NO_INNER =
332 "public class Test {" + PMD.EOL +
333 " public class Inner {" + PMD.EOL +
334 " int foo;" + PMD.EOL +
335 " }" + PMD.EOL +
336 "}";
337
338 private static final String CONTAINS_NO_INNER_WITH_ANON_INNER =
339 "public class Test {" + PMD.EOL +
340 " void bar() {" + PMD.EOL +
341 " foo(new Fuz() { int x = 2;});" + PMD.EOL +
342 " }" + PMD.EOL +
343 "}";
344
345 private static final String TEST_XPATH =
346 "public class Test {" + PMD.EOL +
347 " int x = 2;" + PMD.EOL +
348 " int y = 42;" + PMD.EOL +
349 "}";
350
351 public static junit.framework.Test suite() {
352 return new junit.framework.JUnit4TestAdapter(SimpleNodeTest.class);
353 }
354 }