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   import java.io.InputStream;
9   import java.io.InputStreamReader;
10  import java.util.ArrayList;
11  import java.util.List;
12  import org.jaxen.JaxenException;
13  import org.junit.Test;
14  import net.sourceforge.pmd.lang.LanguageRegistry;
15  import net.sourceforge.pmd.lang.LanguageVersionHandler;
16  import net.sourceforge.pmd.lang.java.JavaLanguageModule;
17  import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression;
18  import net.sourceforge.pmd.lang.java.ast.ASTBooleanLiteral;
19  import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
20  import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
21  import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
22  import net.sourceforge.pmd.lang.java.ast.ASTExpression;
23  import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
24  import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter;
25  import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
26  import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
27  import net.sourceforge.pmd.lang.java.ast.ASTName;
28  import net.sourceforge.pmd.lang.java.ast.ASTNullLiteral;
29  import net.sourceforge.pmd.lang.java.ast.ASTReferenceType;
30  import net.sourceforge.pmd.lang.java.ast.ASTStatementExpression;
31  import net.sourceforge.pmd.lang.java.ast.ASTType;
32  import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration;
33  import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator;
34  import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
35  import net.sourceforge.pmd.lang.java.ast.TypeNode;
36  import net.sourceforge.pmd.lang.java.typeresolution.ClassTypeResolver;
37  import net.sourceforge.pmd.typeresolution.testdata.AnonymousInnerClass;
38  import net.sourceforge.pmd.typeresolution.testdata.ArrayListFound;
39  import net.sourceforge.pmd.typeresolution.testdata.DefaultJavaLangImport;
40  import net.sourceforge.pmd.typeresolution.testdata.EnumWithAnonymousInnerClass;
41  import net.sourceforge.pmd.typeresolution.testdata.ExtraTopLevelClass;
42  import net.sourceforge.pmd.typeresolution.testdata.InnerClass;
43  import net.sourceforge.pmd.typeresolution.testdata.Literals;
44  import net.sourceforge.pmd.typeresolution.testdata.Operators;
45  import net.sourceforge.pmd.typeresolution.testdata.Promotion;
46  
47  
48  public class ClassTypeResolverTest {
49  
50      @Test
51      public void testClassNameExists() {
52          ClassTypeResolver classTypeResolver = new ClassTypeResolver();
53          assertEquals(true, classTypeResolver.classNameExists("java.lang.System"));
54          assertEquals(false, classTypeResolver.classNameExists("im.sure.that.this.does.not.Exist"));
55          assertEquals(true, classTypeResolver.classNameExists("java.awt.List"));
56      }
57  
58      @Test
59      public void acceptanceTest() {
60          ASTCompilationUnit acu = parseAndTypeResolveForClass15(ArrayListFound.class);
61          assertEquals(ArrayListFound.class, acu.getFirstDescendantOfType(ASTTypeDeclaration.class).getType());
62          assertEquals(ArrayListFound.class, acu.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class).getType());
63          ASTImportDeclaration id = acu.getFirstDescendantOfType(ASTImportDeclaration.class);
64          assertEquals("java.util", id.getPackage().getName());
65          assertEquals(ArrayList.class, id.getType());
66          assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTClassOrInterfaceType.class).getType());
67          assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTReferenceType.class).getType());
68          assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTType.class).getType());
69          assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTVariableDeclaratorId.class).getType());
70          assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTVariableDeclarator.class).getType());
71          assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTFieldDeclaration.class).getType());
72  
73          acu = parseAndTypeResolveForClass15(DefaultJavaLangImport.class);
74          assertEquals(String.class, acu.getFirstDescendantOfType(ASTClassOrInterfaceType.class).getType());
75          assertEquals(Override.class, acu.findDescendantsOfType(ASTName.class).get(1).getType());
76      }
77  
78      /**
79       * See bug #1138 Anonymous inner class in enum causes NPE
80       */
81      @Test
82      public void testEnumAnonymousInnerClass() {
83          ASTCompilationUnit acu = parseAndTypeResolveForClass15(EnumWithAnonymousInnerClass.class);
84          Class<?> inner = acu.getFirstDescendantOfType(ASTAllocationExpression.class)
85                  .getFirstDescendantOfType(ASTClassOrInterfaceType.class).getType();
86          assertEquals("net.sourceforge.pmd.typeresolution.testdata.EnumWithAnonymousInnerClass$1",
87                  inner.getName());
88      }
89  
90      @Test
91      public void testExtraTopLevelClass() throws ClassNotFoundException {
92          ASTCompilationUnit acu = parseAndTypeResolveForClass15(ExtraTopLevelClass.class);
93          Class<?> theExtraTopLevelClass = Class.forName("net.sourceforge.pmd.typeresolution.testdata.TheExtraTopLevelClass");
94          // First class
95          ASTTypeDeclaration typeDeclaration = (ASTTypeDeclaration) acu.jjtGetChild(1);
96          assertEquals(ExtraTopLevelClass.class, typeDeclaration.getType());
97          assertEquals(ExtraTopLevelClass.class,
98                  typeDeclaration.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class).getType());
99          // Second class
100         typeDeclaration = (ASTTypeDeclaration) acu.jjtGetChild(2);
101         assertEquals(theExtraTopLevelClass, typeDeclaration.getType());
102         assertEquals(theExtraTopLevelClass,
103                 typeDeclaration.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class).getType());
104     }
105 
106     @Test
107     public void testInnerClass() throws ClassNotFoundException {
108         ASTCompilationUnit acu = parseAndTypeResolveForClass15(InnerClass.class);
109         Class<?> theInnerClass = Class.forName("net.sourceforge.pmd.typeresolution.testdata.InnerClass$TheInnerClass");
110         // Outer class
111         ASTTypeDeclaration typeDeclaration = acu.getFirstDescendantOfType(ASTTypeDeclaration.class);
112         assertEquals(InnerClass.class, typeDeclaration.getType());
113         ASTClassOrInterfaceDeclaration outerClassDeclaration = typeDeclaration.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class);
114         assertEquals(InnerClass.class, outerClassDeclaration.getType());
115         // Inner class
116         assertEquals(theInnerClass,
117                 outerClassDeclaration.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class).getType());
118         // Method parameter as inner class
119         ASTFormalParameter formalParameter = typeDeclaration.getFirstDescendantOfType(ASTFormalParameter.class);
120         assertEquals(theInnerClass, formalParameter.getTypeNode().getType());
121     }
122 
123     @Test
124     public void testAnonymousInnerClass() throws ClassNotFoundException {
125         ASTCompilationUnit acu = parseAndTypeResolveForClass15(AnonymousInnerClass.class);
126         Class<?> theAnonymousInnerClass = Class.forName("net.sourceforge.pmd.typeresolution.testdata.AnonymousInnerClass$1");
127         // Outer class
128         ASTTypeDeclaration typeDeclaration = acu.getFirstDescendantOfType(ASTTypeDeclaration.class);
129         assertEquals(AnonymousInnerClass.class, typeDeclaration.getType());
130         ASTClassOrInterfaceDeclaration outerClassDeclaration = typeDeclaration.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class);
131         assertEquals(AnonymousInnerClass.class, outerClassDeclaration.getType());
132         // Anonymous Inner class
133         assertEquals(theAnonymousInnerClass,
134                 outerClassDeclaration.getFirstDescendantOfType(ASTAllocationExpression.class).getType());
135     }
136 
137     @Test
138     @SuppressWarnings("unchecked")
139     public void testLiterals() throws JaxenException {
140         ASTCompilationUnit acu = parseAndTypeResolveForClass15(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).getFirstDescendantOfType(ASTBooleanLiteral.class).getType());
150         assertEquals(Boolean.TYPE, literals.get(index++).getType());
151 
152         // boolean boolean2 = true;
153         assertEquals(Boolean.TYPE, literals.get(index).getFirstDescendantOfType(ASTBooleanLiteral.class).getType());
154         assertEquals(Boolean.TYPE, literals.get(index++).getType());
155 
156         // Object obj = null;
157         assertNull(literals.get(index).getFirstDescendantOfType(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         // float float3 = 0x08.08p3f;
253         assertEquals(0, literals.get(index).jjtGetNumChildren());
254         assertEquals(Float.TYPE, literals.get(index++).getType());
255 
256         // float float4 = 0xFF;
257         assertEquals(0, literals.get(index).jjtGetNumChildren());
258         assertEquals(Integer.TYPE, literals.get(index++).getType());
259 
260         // float float5 = 'a';
261         assertEquals(0, literals.get(index).jjtGetNumChildren());
262         assertEquals(Character.TYPE, literals.get(index++).getType());
263 
264         // double double1 = 0.0;
265         assertEquals(0, literals.get(index).jjtGetNumChildren());
266         assertEquals(Double.TYPE, literals.get(index++).getType());
267 
268         // double double2 = -10e+01;
269         assertEquals(0, literals.get(index).jjtGetNumChildren());
270         assertEquals(Double.TYPE, literals.get(index++).getType());
271 
272         // double double3 = 0x08.08p3;
273         assertEquals(0, literals.get(index).jjtGetNumChildren());
274         assertEquals(Double.TYPE, literals.get(index++).getType());
275 
276         // double double4 = 0xFF;
277         assertEquals(0, literals.get(index).jjtGetNumChildren());
278         assertEquals(Integer.TYPE, literals.get(index++).getType());
279 
280         // double double5 = 'a';
281         assertEquals(0, literals.get(index).jjtGetNumChildren());
282         assertEquals(Character.TYPE, literals.get(index++).getType());
283 
284         // Make sure we got them all.
285         assertEquals("All literals not tested", index, literals.size());
286     }
287 
288     @Test
289     @SuppressWarnings("unchecked")
290     public void testUnaryNumericPromotion() throws JaxenException {
291         ASTCompilationUnit acu = parseAndTypeResolveForClass15(Promotion.class);
292         List<ASTExpression> expressions = acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryNumericPromotion']]//Expression[UnaryExpression]");
293         int index = 0;
294 
295         assertEquals(Integer.TYPE, expressions.get(index++).getType());
296         assertEquals(Integer.TYPE, expressions.get(index++).getType());
297         assertEquals(Integer.TYPE, expressions.get(index++).getType());
298         assertEquals(Integer.TYPE, expressions.get(index++).getType());
299         assertEquals(Long.TYPE, expressions.get(index++).getType());
300         assertEquals(Float.TYPE, expressions.get(index++).getType());
301         assertEquals(Double.TYPE, expressions.get(index++).getType());
302 
303         // Make sure we got them all.
304         assertEquals("All expressions not tested", index, expressions.size());
305     }
306 
307     @Test
308     @SuppressWarnings("unchecked")
309     public void testBinaryNumericPromotion() throws JaxenException {
310         ASTCompilationUnit acu = parseAndTypeResolveForClass15(Promotion.class);
311         List<ASTExpression> expressions = acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'binaryNumericPromotion']]//Expression[AdditiveExpression]");
312         int index = 0;
313 
314         // LHS = byte
315         assertEquals(Integer.TYPE, expressions.get(index++).getType());
316         assertEquals(Integer.TYPE, expressions.get(index++).getType());
317         assertEquals(Integer.TYPE, expressions.get(index++).getType());
318         assertEquals(Integer.TYPE, expressions.get(index++).getType());
319         assertEquals(Long.TYPE, expressions.get(index++).getType());
320         assertEquals(Float.TYPE, expressions.get(index++).getType());
321         assertEquals(Double.TYPE, expressions.get(index++).getType());
322         // LHS = short
323         assertEquals(Integer.TYPE, expressions.get(index++).getType());
324         assertEquals(Integer.TYPE, expressions.get(index++).getType());
325         assertEquals(Integer.TYPE, expressions.get(index++).getType());
326         assertEquals(Integer.TYPE, expressions.get(index++).getType());
327         assertEquals(Long.TYPE, expressions.get(index++).getType());
328         assertEquals(Float.TYPE, expressions.get(index++).getType());
329         assertEquals(Double.TYPE, expressions.get(index++).getType());
330         // LHS = char
331         assertEquals(Integer.TYPE, expressions.get(index++).getType());
332         assertEquals(Integer.TYPE, expressions.get(index++).getType());
333         assertEquals(Integer.TYPE, expressions.get(index++).getType());
334         assertEquals(Integer.TYPE, expressions.get(index++).getType());
335         assertEquals(Long.TYPE, expressions.get(index++).getType());
336         assertEquals(Float.TYPE, expressions.get(index++).getType());
337         assertEquals(Double.TYPE, expressions.get(index++).getType());
338         // LHS = int
339         assertEquals(Integer.TYPE, expressions.get(index++).getType());
340         assertEquals(Integer.TYPE, expressions.get(index++).getType());
341         assertEquals(Integer.TYPE, expressions.get(index++).getType());
342         assertEquals(Integer.TYPE, expressions.get(index++).getType());
343         assertEquals(Long.TYPE, expressions.get(index++).getType());
344         assertEquals(Float.TYPE, expressions.get(index++).getType());
345         assertEquals(Double.TYPE, expressions.get(index++).getType());
346         // LHS = long
347         assertEquals(Long.TYPE, expressions.get(index++).getType());
348         assertEquals(Long.TYPE, expressions.get(index++).getType());
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(Float.TYPE, expressions.get(index++).getType());
353         assertEquals(Double.TYPE, expressions.get(index++).getType());
354         // LHS = float
355         assertEquals(Float.TYPE, expressions.get(index++).getType());
356         assertEquals(Float.TYPE, expressions.get(index++).getType());
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(Double.TYPE, expressions.get(index++).getType());
362         // LHS = double
363         assertEquals(Double.TYPE, expressions.get(index++).getType());
364         assertEquals(Double.TYPE, expressions.get(index++).getType());
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 
371         // Make sure we got them all.
372         assertEquals("All expressions not tested", index, expressions.size());
373     }
374 
375     @Test
376     @SuppressWarnings("unchecked")
377     public void testBinaryStringPromotion() throws JaxenException {
378         ASTCompilationUnit acu = parseAndTypeResolveForClass15(Promotion.class);
379         List<ASTExpression> expressions = acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'binaryStringPromotion']]//Expression");
380         int index = 0;
381 
382         assertEquals(String.class, expressions.get(index++).getType());
383         assertEquals(String.class, expressions.get(index++).getType());
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 
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 testUnaryLogicalOperators() throws JaxenException {
395         ASTCompilationUnit acu = parseAndTypeResolveForClass15(Operators.class);
396         List<ASTExpression> expressions = acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryLogicalOperators']]//Expression");
397         int index = 0;
398 
399         assertEquals(Boolean.TYPE, expressions.get(index++).getType());
400         assertEquals(Boolean.TYPE, expressions.get(index++).getType());
401 
402         // Make sure we got them all.
403         assertEquals("All expressions not tested", index, expressions.size());
404     }
405 
406     @Test
407     @SuppressWarnings("unchecked")
408     public void testBinaryLogicalOperators() throws JaxenException {
409         ASTCompilationUnit acu = parseAndTypeResolveForClass15(Operators.class);
410         List<ASTExpression> expressions = acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'binaryLogicalOperators']]//Expression");
411         int index = 0;
412 
413         assertEquals(Boolean.TYPE, expressions.get(index++).getType());
414         assertEquals(Boolean.TYPE, expressions.get(index++).getType());
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 
427         // Make sure we got them all.
428         assertEquals("All expressions not tested", index, expressions.size());
429     }
430 
431     @Test
432     @SuppressWarnings("unchecked")
433     public void testUnaryNumericOperators() throws JaxenException {
434         ASTCompilationUnit acu = parseAndTypeResolveForClass15(Operators.class);
435         List<TypeNode> expressions = new ArrayList<TypeNode>();
436         expressions.addAll(acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryNumericOperators']]//Expression"));
437         expressions.addAll(acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryNumericOperators']]//PostfixExpression"));
438         expressions.addAll(acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryNumericOperators']]//PreIncrementExpression"));
439         expressions.addAll(acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryNumericOperators']]//PreDecrementExpression"));
440         int index = 0;
441 
442         assertEquals(Integer.TYPE, expressions.get(index++).getType());
443         assertEquals(Integer.TYPE, expressions.get(index++).getType());
444         assertEquals(Double.TYPE, expressions.get(index++).getType());
445         assertEquals(Double.TYPE, expressions.get(index++).getType());
446         assertEquals(Double.TYPE, expressions.get(index++).getType());
447         assertEquals(Double.TYPE, expressions.get(index++).getType());
448 
449         // Make sure we got them all.
450         assertEquals("All expressions not tested", index, expressions.size());
451     }
452 
453     @Test
454     @SuppressWarnings("unchecked")
455     public void testBinaryNumericOperators() throws JaxenException {
456         ASTCompilationUnit acu = parseAndTypeResolveForClass15(Operators.class);
457         List<ASTExpression> expressions = acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'binaryNumericOperators']]//Expression");
458         int index = 0;
459 
460         assertEquals(Integer.TYPE, expressions.get(index++).getType());
461         assertEquals(Integer.TYPE, expressions.get(index++).getType());
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 
469         // Make sure we got them all.
470         assertEquals("All expressions not tested", index, expressions.size());
471     }
472 
473     @Test
474     @SuppressWarnings("unchecked")
475     public void testAssignmentOperators() throws JaxenException {
476         ASTCompilationUnit acu = parseAndTypeResolveForClass15(Operators.class);
477         List<ASTStatementExpression> expressions = acu.findChildNodesWithXPath("//Block[preceding-sibling::MethodDeclarator[@Image = 'assignmentOperators']]//StatementExpression");
478         int index = 0;
479 
480         assertEquals(Long.TYPE, expressions.get(index++).getType());
481         assertEquals(Long.TYPE, expressions.get(index++).getType());
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 
493         // Make sure we got them all.
494         assertEquals("All expressions not tested", index, expressions.size());
495     }
496 
497     public static junit.framework.Test suite() {
498         return new junit.framework.JUnit4TestAdapter(ClassTypeResolverTest.class);
499     }
500 
501     private ASTCompilationUnit parseAndTypeResolveForClass15(Class<?> clazz) {
502         return parseAndTypeResolveForClass(clazz, "1.5");
503     }
504 
505     // Note: If you're using Eclipse or some other IDE to run this test, you _must_ have the regress folder in
506     // the classpath.  Normally the IDE doesn't put source directories themselves directly in the classpath, only
507     // the output directories are in the classpath.
508     private ASTCompilationUnit parseAndTypeResolveForClass(Class<?> clazz, String version) {
509         String sourceFile = clazz.getName().replace('.', '/') + ".java";
510         InputStream is = ClassTypeResolverTest.class.getClassLoader().getResourceAsStream(sourceFile);
511         if (is == null) {
512             throw new IllegalArgumentException("Unable to find source file " + sourceFile + " for " + clazz);
513         }
514         LanguageVersionHandler languageVersionHandler = LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion(version).getLanguageVersionHandler();
515         ASTCompilationUnit acu = (ASTCompilationUnit) languageVersionHandler.getParser(languageVersionHandler.getDefaultParserOptions()).parse(null, new InputStreamReader(is));
516         languageVersionHandler.getSymbolFacade().start(acu);
517         languageVersionHandler.getTypeResolutionFacade(ClassTypeResolverTest.class.getClassLoader()).start(acu);
518         return acu;
519     }
520 }