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