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