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