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