View Javadoc

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