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