View Javadoc

1   package net.sourceforge.pmd.typeresolution;
2   
3   import static org.junit.Assert.assertEquals;
4   import static org.junit.Assert.assertNull;
5   
6   import java.io.InputStream;
7   import java.io.InputStreamReader;
8   import java.util.ArrayList;
9   import java.util.List;
10  
11  import net.sourceforge.pmd.lang.LanguageVersion;
12  import net.sourceforge.pmd.lang.LanguageVersionHandler;
13  import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression;
14  import net.sourceforge.pmd.lang.java.ast.ASTBooleanLiteral;
15  import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
16  import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
17  import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
18  import net.sourceforge.pmd.lang.java.ast.ASTExpression;
19  import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
20  import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter;
21  import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
22  import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
23  import net.sourceforge.pmd.lang.java.ast.ASTName;
24  import net.sourceforge.pmd.lang.java.ast.ASTNullLiteral;
25  import net.sourceforge.pmd.lang.java.ast.ASTReferenceType;
26  import net.sourceforge.pmd.lang.java.ast.ASTStatementExpression;
27  import net.sourceforge.pmd.lang.java.ast.ASTType;
28  import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration;
29  import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator;
30  import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
31  import net.sourceforge.pmd.lang.java.ast.TypeNode;
32  import net.sourceforge.pmd.lang.java.typeresolution.ClassTypeResolver;
33  import net.sourceforge.pmd.typeresolution.testdata.AnonymousInnerClass;
34  import net.sourceforge.pmd.typeresolution.testdata.ArrayListFound;
35  import net.sourceforge.pmd.typeresolution.testdata.DefaultJavaLangImport;
36  import net.sourceforge.pmd.typeresolution.testdata.ExtraTopLevelClass;
37  import net.sourceforge.pmd.typeresolution.testdata.InnerClass;
38  import net.sourceforge.pmd.typeresolution.testdata.Literals;
39  import net.sourceforge.pmd.typeresolution.testdata.Operators;
40  import net.sourceforge.pmd.typeresolution.testdata.Promotion;
41  
42  import org.jaxen.JaxenException;
43  import org.junit.Test;
44  
45  
46  public class ClassTypeResolverTest {
47  
48  	@Test
49  	public void testClassNameExists() {
50  		ClassTypeResolver classTypeResolver = new ClassTypeResolver();
51  		assertEquals(true, classTypeResolver.classNameExists("java.lang.System"));
52  		assertEquals(false, classTypeResolver.classNameExists("im.sure.that.this.does.not.Exist"));
53  		assertEquals(true, classTypeResolver.classNameExists("java.awt.List"));
54  	}
55  
56  	@Test
57  	public void acceptanceTest() {
58  		ASTCompilationUnit acu = parseAndTypeResolveForClass(ArrayListFound.class);
59  		assertEquals(ArrayListFound.class, acu.getFirstDescendantOfType(ASTTypeDeclaration.class).getType());
60  		assertEquals(ArrayListFound.class, acu.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class).getType());
61  		ASTImportDeclaration id = acu.getFirstDescendantOfType(ASTImportDeclaration.class);
62  		assertEquals("java.util", id.getPackage().getName());
63  		assertEquals(java.util.ArrayList.class, id.getType());
64  		assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTClassOrInterfaceType.class).getType());
65  		assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTReferenceType.class).getType());
66  		assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTType.class).getType());
67  		assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTVariableDeclaratorId.class).getType());
68  		assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTVariableDeclarator.class).getType());
69  		assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTFieldDeclaration.class).getType());
70  
71  		acu = parseAndTypeResolveForClass(DefaultJavaLangImport.class);
72  		assertEquals(String.class, acu.getFirstDescendantOfType(ASTClassOrInterfaceType.class).getType());
73  		assertEquals(Override.class, acu.findDescendantsOfType(ASTName.class).get(1).getType());
74  	}
75  
76  	@Test
77  	public void testExtraTopLevelClass() throws ClassNotFoundException {
78  		ASTCompilationUnit acu = parseAndTypeResolveForClass(ExtraTopLevelClass.class);
79  		Class<?> theExtraTopLevelClass = Class.forName("net.sourceforge.pmd.typeresolution.testdata.TheExtraTopLevelClass");
80  		// First class
81  		ASTTypeDeclaration typeDeclaration = (ASTTypeDeclaration)acu.jjtGetChild(1);
82  		assertEquals(ExtraTopLevelClass.class, typeDeclaration.getType());
83  		assertEquals(ExtraTopLevelClass.class,
84  				typeDeclaration.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class).getType());
85  		// Second class
86  		typeDeclaration = (ASTTypeDeclaration)acu.jjtGetChild(2);
87  		assertEquals(theExtraTopLevelClass, typeDeclaration.getType());
88  		assertEquals(theExtraTopLevelClass,
89  				typeDeclaration.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class).getType());
90  	}
91  
92  	@Test
93  	public void testInnerClass() throws ClassNotFoundException {
94  		ASTCompilationUnit acu = parseAndTypeResolveForClass(InnerClass.class);
95  		Class<?> theInnerClass = Class.forName("net.sourceforge.pmd.typeresolution.testdata.InnerClass$TheInnerClass");
96  		// Outer class
97  		ASTTypeDeclaration typeDeclaration = acu.getFirstDescendantOfType(ASTTypeDeclaration.class);
98  		assertEquals(InnerClass.class, typeDeclaration.getType());
99  		ASTClassOrInterfaceDeclaration outerClassDeclaration = typeDeclaration.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class);
100 		assertEquals(InnerClass.class, outerClassDeclaration.getType());
101 		// Inner class
102 		assertEquals(theInnerClass,
103 				outerClassDeclaration.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class).getType());
104 		// Method parameter as inner class
105 		ASTFormalParameter formalParameter = typeDeclaration.getFirstDescendantOfType(ASTFormalParameter.class);
106 		assertEquals(theInnerClass, formalParameter.getTypeNode().getType());
107 	}
108 
109 	@Test
110 	public void testAnonymousInnerClass() throws ClassNotFoundException {
111 		ASTCompilationUnit acu = parseAndTypeResolveForClass(AnonymousInnerClass.class);
112 		Class<?> theAnonymousInnerClass = Class.forName("net.sourceforge.pmd.typeresolution.testdata.AnonymousInnerClass$1");
113 		// Outer class
114 		ASTTypeDeclaration typeDeclaration = acu.getFirstDescendantOfType(ASTTypeDeclaration.class);
115 		assertEquals(AnonymousInnerClass.class, typeDeclaration.getType());
116 		ASTClassOrInterfaceDeclaration outerClassDeclaration = typeDeclaration.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class);
117 		assertEquals(AnonymousInnerClass.class, outerClassDeclaration.getType());
118 		// Anonymous Inner class
119 		assertEquals(theAnonymousInnerClass,
120 				outerClassDeclaration.getFirstDescendantOfType(ASTAllocationExpression.class).getType());
121 	}
122 
123 	@Test
124 	@SuppressWarnings("unchecked")
125 	public void testLiterals() throws JaxenException {
126 		ASTCompilationUnit acu = parseAndTypeResolveForClass(Literals.class);
127 		List<ASTLiteral> literals = acu.findChildNodesWithXPath("//Literal");
128 		int index = 0;
129 
130 		// String s = "s";
131 		assertEquals(0, literals.get(index).jjtGetNumChildren());
132 		assertEquals(String.class, literals.get(index++).getType());
133 
134 		// boolean boolean1 = false;
135 		assertEquals(Boolean.TYPE, literals.get(index).getFirstDescendantOfType(ASTBooleanLiteral.class).getType());
136 		assertEquals(Boolean.TYPE, literals.get(index++).getType());
137 
138 		// boolean boolean2 = true;
139 		assertEquals(Boolean.TYPE, literals.get(index).getFirstDescendantOfType(ASTBooleanLiteral.class).getType());
140 		assertEquals(Boolean.TYPE, literals.get(index++).getType());
141 
142 		// Object obj = null;
143 		assertNull(literals.get(index).getFirstDescendantOfType(ASTNullLiteral.class).getType());
144 		assertNull(literals.get(index++).getType());
145 
146 		// byte byte1 = 0;
147 		assertEquals(0, literals.get(index).jjtGetNumChildren());
148 		assertEquals(Integer.TYPE, literals.get(index++).getType());
149 
150 		// byte byte2 = 0x0F;
151 		assertEquals(0, literals.get(index).jjtGetNumChildren());
152 		assertEquals(Integer.TYPE, literals.get(index++).getType());
153 
154 		// byte byte3 = -007;
155 		assertEquals(0, literals.get(index).jjtGetNumChildren());
156 		assertEquals(Integer.TYPE, literals.get(index++).getType());
157 
158 		// short short1 = 0;
159 		assertEquals(0, literals.get(index).jjtGetNumChildren());
160 		assertEquals(Integer.TYPE, literals.get(index++).getType());
161 
162 		// short short2 = 0x0F;
163 		assertEquals(0, literals.get(index).jjtGetNumChildren());
164 		assertEquals(Integer.TYPE, literals.get(index++).getType());
165 
166 		// short short3 = -007;
167 		assertEquals(0, literals.get(index).jjtGetNumChildren());
168 		assertEquals(Integer.TYPE, literals.get(index++).getType());
169 
170 		// char char1 = 0;
171 		assertEquals(0, literals.get(index).jjtGetNumChildren());
172 		assertEquals(Integer.TYPE, literals.get(index++).getType());
173 
174 		// char char2 = 0x0F;
175 		assertEquals(0, literals.get(index).jjtGetNumChildren());
176 		assertEquals(Integer.TYPE, literals.get(index++).getType());
177 
178 		// char char3 = 007;
179 		assertEquals(0, literals.get(index).jjtGetNumChildren());
180 		assertEquals(Integer.TYPE, literals.get(index++).getType());
181 
182 		// char char4 = 'a';
183 		assertEquals(0, literals.get(index).jjtGetNumChildren());
184 		assertEquals(Character.TYPE, literals.get(index++).getType());
185 
186 		// int int1 = 0;
187 		assertEquals(0, literals.get(index).jjtGetNumChildren());
188 		assertEquals(Integer.TYPE, literals.get(index++).getType());
189 
190 		// int int2 = 0x0F;
191 		assertEquals(0, literals.get(index).jjtGetNumChildren());
192 		assertEquals(Integer.TYPE, literals.get(index++).getType());
193 
194 		// int int3 = -007;
195 		assertEquals(0, literals.get(index).jjtGetNumChildren());
196 		assertEquals(Integer.TYPE, literals.get(index++).getType());
197 
198 		// int int4 = 'a';
199 		assertEquals(0, literals.get(index).jjtGetNumChildren());
200 		assertEquals(Character.TYPE, literals.get(index++).getType());
201 
202 		// long long1 = 0;
203 		assertEquals(0, literals.get(index).jjtGetNumChildren());
204 		assertEquals(Integer.TYPE, literals.get(index++).getType());
205 
206 		// long long2 = 0x0F;
207 		assertEquals(0, literals.get(index).jjtGetNumChildren());
208 		assertEquals(Integer.TYPE, literals.get(index++).getType());
209 
210 		// long long3 = -007;
211 		assertEquals(0, literals.get(index).jjtGetNumChildren());
212 		assertEquals(Integer.TYPE, literals.get(index++).getType());
213 
214 		// long long4 = 0L;
215 		assertEquals(0, literals.get(index).jjtGetNumChildren());
216 		assertEquals(Long.TYPE, literals.get(index++).getType());
217 
218 		// long long5 = 0x0Fl;
219 		assertEquals(0, literals.get(index).jjtGetNumChildren());
220 		assertEquals(Long.TYPE, literals.get(index++).getType());
221 
222 		// long long6 = -007L;
223 		assertEquals(0, literals.get(index).jjtGetNumChildren());
224 		assertEquals(Long.TYPE, literals.get(index++).getType());
225 
226 		// long long7 = 'a';
227 		assertEquals(0, literals.get(index).jjtGetNumChildren());
228 		assertEquals(Character.TYPE, literals.get(index++).getType());
229 
230 		// float float1 = 0.0f;
231 		assertEquals(0, literals.get(index).jjtGetNumChildren());
232 		assertEquals(Float.TYPE, literals.get(index++).getType());
233 
234 		// float float2 = -10e+01f;
235 		assertEquals(0, literals.get(index).jjtGetNumChildren());
236 		assertEquals(Float.TYPE, literals.get(index++).getType());
237 
238 		// float float3 = 0x08.08p3f;
239 		assertEquals(0, literals.get(index).jjtGetNumChildren());
240 		assertEquals(Float.TYPE, literals.get(index++).getType());
241 
242 		// float float4 = 0xFF;
243 		assertEquals(0, literals.get(index).jjtGetNumChildren());
244 		assertEquals(Integer.TYPE, literals.get(index++).getType());
245 
246 		// float float5 = 'a';
247 		assertEquals(0, literals.get(index).jjtGetNumChildren());
248 		assertEquals(Character.TYPE, literals.get(index++).getType());
249 
250 		// double double1 = 0.0;
251 		assertEquals(0, literals.get(index).jjtGetNumChildren());
252 		assertEquals(Double.TYPE, literals.get(index++).getType());
253 
254 		// double double2 = -10e+01;
255 		assertEquals(0, literals.get(index).jjtGetNumChildren());
256 		assertEquals(Double.TYPE, literals.get(index++).getType());
257 
258 		// double double3 = 0x08.08p3;
259 		assertEquals(0, literals.get(index).jjtGetNumChildren());
260 		assertEquals(Double.TYPE, literals.get(index++).getType());
261 
262 		// double double4 = 0xFF;
263 		assertEquals(0, literals.get(index).jjtGetNumChildren());
264 		assertEquals(Integer.TYPE, literals.get(index++).getType());
265 
266 		// double double5 = 'a';
267 		assertEquals(0, literals.get(index).jjtGetNumChildren());
268 		assertEquals(Character.TYPE, literals.get(index++).getType());
269 
270 		// Make sure we got them all.
271 		assertEquals("All literals not tested", index, literals.size());
272 	}
273 
274 	@Test
275 	@SuppressWarnings("unchecked")
276 	public void testUnaryNumericPromotion() throws JaxenException {
277 		ASTCompilationUnit acu = parseAndTypeResolveForClass(Promotion.class);
278 		List<ASTExpression> expressions = acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryNumericPromotion']]//Expression[UnaryExpression]");
279 		int index = 0;
280 
281 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
282 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
283 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
284 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
285 		assertEquals(Long.TYPE, expressions.get(index++).getType());
286 		assertEquals(Float.TYPE, expressions.get(index++).getType());
287 		assertEquals(Double.TYPE, expressions.get(index++).getType());
288 
289 		// Make sure we got them all.
290 		assertEquals("All expressions not tested", index, expressions.size());
291 	}
292 
293 	@Test
294 	@SuppressWarnings("unchecked")
295 	public void testBinaryNumericPromotion() throws JaxenException {
296 		ASTCompilationUnit acu = parseAndTypeResolveForClass(Promotion.class);
297 		List<ASTExpression> expressions = acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'binaryNumericPromotion']]//Expression[AdditiveExpression]");
298 		int index = 0;
299 
300 		// LHS = byte
301 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
302 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
303 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
304 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
305 		assertEquals(Long.TYPE, expressions.get(index++).getType());
306 		assertEquals(Float.TYPE, expressions.get(index++).getType());
307 		assertEquals(Double.TYPE, expressions.get(index++).getType());
308 		// LHS = short
309 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
310 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
311 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
312 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
313 		assertEquals(Long.TYPE, expressions.get(index++).getType());
314 		assertEquals(Float.TYPE, expressions.get(index++).getType());
315 		assertEquals(Double.TYPE, expressions.get(index++).getType());
316 		// LHS = char
317 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
318 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
319 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
320 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
321 		assertEquals(Long.TYPE, expressions.get(index++).getType());
322 		assertEquals(Float.TYPE, expressions.get(index++).getType());
323 		assertEquals(Double.TYPE, expressions.get(index++).getType());
324 		// LHS = int
325 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
326 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
327 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
328 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
329 		assertEquals(Long.TYPE, expressions.get(index++).getType());
330 		assertEquals(Float.TYPE, expressions.get(index++).getType());
331 		assertEquals(Double.TYPE, expressions.get(index++).getType());
332 		// LHS = long
333 		assertEquals(Long.TYPE, expressions.get(index++).getType());
334 		assertEquals(Long.TYPE, expressions.get(index++).getType());
335 		assertEquals(Long.TYPE, expressions.get(index++).getType());
336 		assertEquals(Long.TYPE, expressions.get(index++).getType());
337 		assertEquals(Long.TYPE, expressions.get(index++).getType());
338 		assertEquals(Float.TYPE, expressions.get(index++).getType());
339 		assertEquals(Double.TYPE, expressions.get(index++).getType());
340 		// LHS = float
341 		assertEquals(Float.TYPE, expressions.get(index++).getType());
342 		assertEquals(Float.TYPE, expressions.get(index++).getType());
343 		assertEquals(Float.TYPE, expressions.get(index++).getType());
344 		assertEquals(Float.TYPE, expressions.get(index++).getType());
345 		assertEquals(Float.TYPE, expressions.get(index++).getType());
346 		assertEquals(Float.TYPE, expressions.get(index++).getType());
347 		assertEquals(Double.TYPE, expressions.get(index++).getType());
348 		// LHS = double
349 		assertEquals(Double.TYPE, expressions.get(index++).getType());
350 		assertEquals(Double.TYPE, expressions.get(index++).getType());
351 		assertEquals(Double.TYPE, expressions.get(index++).getType());
352 		assertEquals(Double.TYPE, expressions.get(index++).getType());
353 		assertEquals(Double.TYPE, expressions.get(index++).getType());
354 		assertEquals(Double.TYPE, expressions.get(index++).getType());
355 		assertEquals(Double.TYPE, expressions.get(index++).getType());
356 
357 		// Make sure we got them all.
358 		assertEquals("All expressions not tested", index, expressions.size());
359 	}
360 
361 	@Test
362 	@SuppressWarnings("unchecked")
363 	public void testBinaryStringPromotion() throws JaxenException {
364 		ASTCompilationUnit acu = parseAndTypeResolveForClass(Promotion.class);
365 		List<ASTExpression> expressions = acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'binaryStringPromotion']]//Expression");
366 		int index = 0;
367 
368 		assertEquals(String.class, expressions.get(index++).getType());
369 		assertEquals(String.class, expressions.get(index++).getType());
370 		assertEquals(String.class, expressions.get(index++).getType());
371 		assertEquals(String.class, expressions.get(index++).getType());
372 		assertEquals(String.class, expressions.get(index++).getType());
373 
374 		// Make sure we got them all.
375 		assertEquals("All expressions not tested", index, expressions.size());
376 	}
377 
378 	@Test
379 	@SuppressWarnings("unchecked")
380 	public void testUnaryLogicalOperators() throws JaxenException {
381 		ASTCompilationUnit acu = parseAndTypeResolveForClass(Operators.class);
382 		List<ASTExpression> expressions = acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryLogicalOperators']]//Expression");
383 		int index = 0;
384 
385 		assertEquals(Boolean.TYPE, expressions.get(index++).getType());
386 		assertEquals(Boolean.TYPE, expressions.get(index++).getType());
387 
388 		// Make sure we got them all.
389 		assertEquals("All expressions not tested", index, expressions.size());
390 	}
391 
392 	@Test
393 	@SuppressWarnings("unchecked")
394 	public void testBinaryLogicalOperators() throws JaxenException {
395 		ASTCompilationUnit acu = parseAndTypeResolveForClass(Operators.class);
396 		List<ASTExpression> expressions = acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'binaryLogicalOperators']]//Expression");
397 		int index = 0;
398 
399 		assertEquals(Boolean.TYPE, expressions.get(index++).getType());
400 		assertEquals(Boolean.TYPE, expressions.get(index++).getType());
401 		assertEquals(Boolean.TYPE, expressions.get(index++).getType());
402 		assertEquals(Boolean.TYPE, expressions.get(index++).getType());
403 		assertEquals(Boolean.TYPE, expressions.get(index++).getType());
404 		assertEquals(Boolean.TYPE, expressions.get(index++).getType());
405 		assertEquals(Boolean.TYPE, expressions.get(index++).getType());
406 		assertEquals(Boolean.TYPE, expressions.get(index++).getType());
407 		assertEquals(Boolean.TYPE, expressions.get(index++).getType());
408 		assertEquals(Boolean.TYPE, expressions.get(index++).getType());
409 		assertEquals(Boolean.TYPE, expressions.get(index++).getType());
410 		assertEquals(Boolean.TYPE, expressions.get(index++).getType());
411 		assertEquals(Boolean.TYPE, expressions.get(index++).getType());
412 
413 		// Make sure we got them all.
414 		assertEquals("All expressions not tested", index, expressions.size());
415 	}
416 
417 	@Test
418 	@SuppressWarnings("unchecked")
419 	public void testUnaryNumericOperators() throws JaxenException {
420 		ASTCompilationUnit acu = parseAndTypeResolveForClass(Operators.class);
421 		List<TypeNode> expressions = new ArrayList<TypeNode>();
422 		expressions.addAll(acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryNumericOperators']]//Expression"));
423 		expressions.addAll(acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryNumericOperators']]//PostfixExpression"));
424 		expressions.addAll(acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryNumericOperators']]//PreIncrementExpression"));
425 		expressions.addAll(acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryNumericOperators']]//PreDecrementExpression"));
426 		int index = 0;
427 
428 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
429 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
430 		assertEquals(Double.TYPE, expressions.get(index++).getType());
431 		assertEquals(Double.TYPE, expressions.get(index++).getType());
432 		assertEquals(Double.TYPE, expressions.get(index++).getType());
433 		assertEquals(Double.TYPE, expressions.get(index++).getType());
434 
435 		// Make sure we got them all.
436 		assertEquals("All expressions not tested", index, expressions.size());
437 	}
438 
439 	@Test
440 	@SuppressWarnings("unchecked")
441 	public void testBinaryNumericOperators() throws JaxenException {
442 		ASTCompilationUnit acu = parseAndTypeResolveForClass(Operators.class);
443 		List<ASTExpression> expressions = acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'binaryNumericOperators']]//Expression");
444 		int index = 0;
445 
446 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
447 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
448 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
449 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
450 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
451 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
452 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
453 		assertEquals(Integer.TYPE, expressions.get(index++).getType());
454 
455 		// Make sure we got them all.
456 		assertEquals("All expressions not tested", index, expressions.size());
457 	}
458 
459 	@Test
460 	@SuppressWarnings("unchecked")
461 	public void testAssignmentOperators() throws JaxenException {
462 		ASTCompilationUnit acu = parseAndTypeResolveForClass(Operators.class);
463 		List<ASTStatementExpression> expressions = acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'assignmentOperators']]//StatementExpression");
464 		int index = 0;
465 
466 		assertEquals(Long.TYPE, expressions.get(index++).getType());
467 		assertEquals(Long.TYPE, expressions.get(index++).getType());
468 		assertEquals(Long.TYPE, expressions.get(index++).getType());
469 		assertEquals(Long.TYPE, expressions.get(index++).getType());
470 		assertEquals(Long.TYPE, expressions.get(index++).getType());
471 		assertEquals(Long.TYPE, expressions.get(index++).getType());
472 		assertEquals(Long.TYPE, expressions.get(index++).getType());
473 		assertEquals(Long.TYPE, expressions.get(index++).getType());
474 		assertEquals(Long.TYPE, expressions.get(index++).getType());
475 		assertEquals(Long.TYPE, expressions.get(index++).getType());
476 		assertEquals(Long.TYPE, expressions.get(index++).getType());
477 		assertEquals(Long.TYPE, expressions.get(index++).getType());
478 
479 		// Make sure we got them all.
480 		assertEquals("All expressions not tested", index, expressions.size());
481 	}
482 
483 	public static junit.framework.Test suite() {
484 		return new junit.framework.JUnit4TestAdapter(ClassTypeResolverTest.class);
485 	}
486 
487 	// Note: If you're using Eclipse or some other IDE to run this test, you _must_ have the regress folder in
488 	// the classpath.  Normally the IDE doesn't put source directories themselves directly in the classpath, only
489 	// the output directories are in the classpath.
490 	private ASTCompilationUnit parseAndTypeResolveForClass(Class<?> clazz) {
491 		String sourceFile = clazz.getName().replace('.', '/') + ".java";
492 		InputStream is = ClassTypeResolverTest.class.getClassLoader().getResourceAsStream(sourceFile);
493 		if (is == null) {
494 			throw new IllegalArgumentException("Unable to find source file " + sourceFile + " for " + clazz);
495 		}
496 		LanguageVersionHandler languageVersionHandler = LanguageVersion.JAVA_15.getLanguageVersionHandler();
497 		ASTCompilationUnit acu = (ASTCompilationUnit)languageVersionHandler.getParser(languageVersionHandler.getDefaultParserOptions()).parse(null, new InputStreamReader(is));
498 		languageVersionHandler.getSymbolFacade().start(acu);
499 		languageVersionHandler.getTypeResolutionFacade(ClassTypeResolverTest.class.getClassLoader()).start(acu);
500 		return acu;
501 	}
502 }