1   package test.net.sourceforge.pmd.ast;
2   
3   import junit.framework.TestCase;
4   import net.sourceforge.pmd.PMD;
5   import net.sourceforge.pmd.TargetJDK1_3;
6   import net.sourceforge.pmd.TargetJDK1_4;
7   import net.sourceforge.pmd.TargetJDK1_5;
8   import net.sourceforge.pmd.TargetJDKVersion;
9   import net.sourceforge.pmd.ast.JavaParser;
10  import net.sourceforge.pmd.ast.ParseException;
11  
12  import java.io.StringReader;
13  
14  public class JDKVersionTest extends TestCase  {
15  
16      // enum keyword/identifier
17      public void testEnumAsKeywordShouldFailWith14() throws Throwable {
18          try {
19              JavaParser p = new TargetJDK1_4().createParser(new StringReader(JDK15_ENUM));
20              p.CompilationUnit();
21              throw new Error("JDK 1.4 parser should have failed to parse enum used as keyword");
22          } catch (ParseException e) {}    // cool
23      }
24  
25      public void testEnumAsIdentifierShouldPassWith14() throws Throwable {
26          JavaParser p = new TargetJDK1_4().createParser(new StringReader(JDK14_ENUM));
27          p.CompilationUnit();
28      }
29  
30      public void testEnumAsKeywordShouldPassWith15() throws Throwable {
31          JavaParser p = new TargetJDK1_5().createParser(new StringReader(JDK15_ENUM));
32          p.CompilationUnit();
33      }
34  
35      public void testEnumAsIdentifierShouldFailWith15() throws Throwable {
36          try {
37              TargetJDKVersion jdk = new TargetJDK1_5();
38              JavaParser p = jdk.createParser(new StringReader(JDK14_ENUM));
39              p.CompilationUnit();
40              throw new Error("JDK 1.5 parser should have failed to parse enum used as identifier");
41          } catch (ParseException e) {}    // cool
42      }
43      // enum keyword/identifier
44  
45      // assert keyword/identifier
46      public void testAssertAsKeywordVariantsSucceedWith1_4() {
47          (new TargetJDK1_4()).createParser(new StringReader(ASSERT_TEST1)).CompilationUnit();
48          (new TargetJDK1_4()).createParser(new StringReader(ASSERT_TEST2)).CompilationUnit();
49          (new TargetJDK1_4()).createParser(new StringReader(ASSERT_TEST3)).CompilationUnit();
50          (new TargetJDK1_4()).createParser(new StringReader(ASSERT_TEST4)).CompilationUnit();
51      }
52  
53      public void testAssertAsVariableDeclIdentifierFailsWith1_4() {
54          try {
55              (new TargetJDK1_4()).createParser(new StringReader(ASSERT_TEST5)).CompilationUnit();
56              throw new RuntimeException("Usage of assert as identifier should have failed with 1.4");
57          } catch (ParseException pe) {
58              // cool
59          }
60      }
61  
62      public void testAssertAsMethodNameIdentifierFailsWith1_4() {
63          try {
64              (new TargetJDK1_4()).createParser(new StringReader(ASSERT_TEST7)).CompilationUnit();
65              throw new RuntimeException("Usage of assert as identifier should have failed with 1.4");
66          } catch (ParseException pe) {
67              // cool
68          }
69      }
70  
71      public void testAssertAsIdentifierSucceedsWith1_3() {
72          JavaParser jp = (new TargetJDK1_3()).createParser(new StringReader(ASSERT_TEST5));
73          jp.CompilationUnit();
74      }
75  
76      public void testAssertAsKeywordFailsWith1_3() {
77          try {
78              JavaParser jp = (new TargetJDK1_3()).createParser(new StringReader(ASSERT_TEST6));
79              jp.CompilationUnit();
80              throw new RuntimeException("Usage of assert as keyword should have failed with 1.3");
81          } catch (ParseException pe) {
82              // cool
83          }
84      }
85      // assert keyword/identifier
86  
87      public void testVarargsShouldPassWith15() throws Throwable {
88          JavaParser p = new TargetJDK1_5().createParser(new StringReader(JDK15_VARARGS));
89          p.CompilationUnit();
90      }
91  
92      public void testVarargsShouldFailWith14() throws Throwable {
93          try {
94              JavaParser p = new TargetJDK1_4().createParser(new StringReader(JDK15_VARARGS));
95              p.CompilationUnit();
96              fail("Should have throw ParseException!");
97          } catch (ParseException pe) {
98              // cool
99          }
100     }
101 
102     public void testJDK15ForLoopSyntaxShouldPassWith15() throws Throwable {
103         JavaParser p = new TargetJDK1_5().createParser(new StringReader(JDK15_FORLOOP));
104         p.CompilationUnit();
105     }
106 
107     public void testJDK15ForLoopSyntaxWithModifiers() throws Throwable {
108         JavaParser p = new TargetJDK1_5().createParser(new StringReader(JDK15_FORLOOP_WITH_MODIFIER));
109         p.CompilationUnit();
110     }
111 
112     public void testJDK15ForLoopShouldFailWith14() throws Throwable {
113         try {
114             JavaParser p = new TargetJDK1_4().createParser(new StringReader(JDK15_FORLOOP));
115             p.CompilationUnit();
116             fail("Should have throw ParseException!");
117         } catch (ParseException pe) {
118             // cool
119         }
120     }
121 
122     public void testJDK15GenericsSyntaxShouldPassWith15() throws Throwable {
123         JavaParser p = new TargetJDK1_5().createParser(new StringReader(JDK15_GENERICS));
124         p.CompilationUnit();
125     }
126 
127     public void testVariousParserBugs() throws Throwable {
128         JavaParser p = new TargetJDK1_5().createParser(new StringReader(FIELDS_BUG));
129         p.CompilationUnit();
130         p = new TargetJDK1_5().createParser(new StringReader(GT_BUG));
131         p.CompilationUnit();
132         p = new TargetJDK1_5().createParser(new StringReader(ANNOTATIONS_BUG));
133         p.CompilationUnit();
134         p = new TargetJDK1_5().createParser(new StringReader(GENERIC_IN_FIELD));
135         p.CompilationUnit();
136     }
137 
138     public void testNestedClassInMethodBug() throws Throwable {
139         JavaParser p = new TargetJDK1_5().createParser(new StringReader(INNER_BUG));
140         p.CompilationUnit();
141         p = new TargetJDK1_5().createParser(new StringReader(INNER_BUG2));
142         p.CompilationUnit();
143     }
144 
145     public void testGenericsInMethodCall() throws Throwable {
146         JavaParser p = new TargetJDK1_5().createParser(new StringReader(GENERIC_IN_METHOD_CALL));
147         p.CompilationUnit();
148     }
149 
150     public void testGenericINAnnotation() throws Throwable {
151         JavaParser p = new TargetJDK1_5().createParser(new StringReader(GENERIC_IN_ANNOTATION));
152         p.CompilationUnit();
153     }
154 
155     public void testGenericReturnType() throws Throwable {
156         JavaParser p = new TargetJDK1_5().createParser(new StringReader(GENERIC_RETURN_TYPE));
157         p.CompilationUnit();
158     }
159 
160     public void testMultipleGenerics() throws Throwable {
161         JavaParser p = new TargetJDK1_5().createParser(new StringReader(FUNKY_GENERICS));
162         p.CompilationUnit();
163         p = new TargetJDK1_5().createParser(new StringReader(MULTIPLE_GENERICS));
164         p.CompilationUnit();
165     }
166 
167     public void testAnnotatedParams() throws Throwable {
168         JavaParser p = new TargetJDK1_5().createParser(new StringReader(ANNOTATED_PARAMS));
169         p.CompilationUnit();
170     }
171 
172     public void testAnnotatedLocals() throws Throwable {
173         JavaParser p = new TargetJDK1_5().createParser(new StringReader(ANNOTATED_LOCALS));
174         p.CompilationUnit();
175     }
176 
177     private static final String ANNOTATED_LOCALS =
178     "public class Foo {" + PMD.EOL +
179     " void bar() {" + PMD.EOL +
180     "  @SuppressWarnings(\"foo\") int y = 5;" + PMD.EOL +
181     " }" + PMD.EOL +
182     "}";
183 
184     private static final String ANNOTATED_PARAMS =
185     "public class Foo {" + PMD.EOL +
186     " void bar(@SuppressWarnings(\"foo\") int x) {}" + PMD.EOL +
187     "}";
188 
189     private static final String ASSERT_TEST1 =
190     "public class Foo {" + PMD.EOL +
191     " void bar() {" + PMD.EOL +
192     "  assert x == 2;" + PMD.EOL +
193     " }" + PMD.EOL +
194     "}";
195 
196     private static final String ASSERT_TEST2 =
197     "public class Foo {" + PMD.EOL +
198     " void bar() {" + PMD.EOL +
199     "  assert (x == 2);" + PMD.EOL +
200     " }" + PMD.EOL +
201     "}";
202 
203     private static final String ASSERT_TEST3 =
204     "public class Foo {" + PMD.EOL +
205     " void bar() {" + PMD.EOL +
206     "  assert (x==2) : \"hi!\";" + PMD.EOL +
207     " }" + PMD.EOL +
208     "}";
209 
210     private static final String ASSERT_TEST4 =
211     "public class Foo {" + PMD.EOL +
212     " void bar() {" + PMD.EOL +
213     "  assert (x==2) : \"hi!\";" + PMD.EOL +
214     " }" + PMD.EOL +
215     "}";
216 
217     private static final String ASSERT_TEST5 =
218     "public class Foo {" + PMD.EOL +
219     "  int assert = 2;" + PMD.EOL +
220     "}";
221 
222     private static final String ASSERT_TEST6 =
223     "public class Foo {" + PMD.EOL +
224     " void foo() {" + PMD.EOL +
225     "  assert (x == 2) : \"hi!\";" + PMD.EOL +
226     " }" + PMD.EOL +
227     "}";
228 
229     private static final String ASSERT_TEST7 =
230     "public class Foo {" + PMD.EOL +
231     " void assert() {}" + PMD.EOL +
232     "}";
233 
234     private static final String JDK15_ENUM =
235     "public class Test {" + PMD.EOL +
236     " enum Season { winter, spring, summer, fall };" + PMD.EOL +
237     "}";
238 
239     private static final String JDK14_ENUM =
240     "public class Test {" + PMD.EOL +
241     " int enum;" + PMD.EOL +
242     "}";
243 
244     private static final String JDK15_VARARGS =
245     "public class Test {" + PMD.EOL +
246     " void bar(Object ... args) {}" + PMD.EOL +
247     "}";
248 
249     private static final String JDK15_FORLOOP =
250     "public class Test {" + PMD.EOL +
251     " void foo(List list) {" + PMD.EOL +
252     "  for (Integer i : list) {}" + PMD.EOL +
253     " }" + PMD.EOL +
254     "}";
255 
256     private static final String JDK15_FORLOOP_WITH_MODIFIER =
257     "public class Test {" + PMD.EOL +
258     " void foo(List list) {" + PMD.EOL +
259     "  for (final Integer i : list) {}" + PMD.EOL +
260     " }" + PMD.EOL +
261     "}";
262 
263     private static final String JDK15_GENERICS =
264     "public class Test {" + PMD.EOL +
265     "  ArrayList<Integer> list =  new ArrayList<Integer>();" + PMD.EOL +
266     "}";
267 
268     private static final String FIELDS_BUG =
269     "public class Test {" + PMD.EOL +
270     "  private Foo bar;" + PMD.EOL +
271     "}";
272 
273     private static final String GT_BUG =
274     "public class Test {" + PMD.EOL +
275     "  int y = x > 32;" + PMD.EOL +
276     "}";
277 
278     private static final String ANNOTATIONS_BUG =
279     "@Target(ElementType.METHOD)" + PMD.EOL +
280     "public @interface Foo {" + PMD.EOL +
281     "}";
282 
283     private static final String GENERIC_IN_FIELD =
284     "public class Foo {" + PMD.EOL +
285     " Class<Double> foo = (Class<Double>)clazz;" + PMD.EOL +
286     "}";
287 
288     private static final String GENERIC_IN_ANNOTATION =
289     "public class Foo {" + PMD.EOL +
290     " public <A extends Annotation> A foo(Class<A> c) {"  + PMD.EOL +
291     "  return null;"  + PMD.EOL +
292     " }" + PMD.EOL +
293     "}";
294 
295     private static final String INNER_BUG =
296     "public class Test {" + PMD.EOL +
297     "  void bar() {" + PMD.EOL +
298     "   final class Inner {};" + PMD.EOL +
299     "   Inner i = new Inner();" + PMD.EOL +
300     "  }" + PMD.EOL +
301     "}";
302 
303     private static final String INNER_BUG2 =
304     "public class Test {" + PMD.EOL +
305     "  void bar() {" + PMD.EOL +
306     "   class Inner {};" + PMD.EOL +
307     "   Inner i = new Inner();" + PMD.EOL +
308     "  }" + PMD.EOL +
309     "}";
310 
311     private static final String GENERIC_IN_METHOD_CALL =
312     "public class Test {" + PMD.EOL +
313     "  List<String> test() {" + PMD.EOL +
314     "   return Collections.<String>emptyList();" + PMD.EOL +
315     "  }" + PMD.EOL +
316     "}";
317 
318     private static final String GENERIC_RETURN_TYPE =
319     "public class Test {" + PMD.EOL +
320     "  public static <String> String test(String x) {" + PMD.EOL +
321     "   return x;" + PMD.EOL +
322     "  }" + PMD.EOL +
323     "}";
324 
325     // See java/lang/concurrent/ConcurrentHashMap
326     private static final String MULTIPLE_GENERICS =
327     "public class Foo<K,V> {" + PMD.EOL +
328     "  public <A extends K, B extends V> Foo(Bar<A,B> t) {}" + PMD.EOL +
329     "}";
330 
331     // See java/lang/concurrent/CopyOnWriteArraySet
332     private static final String FUNKY_GENERICS =
333     "public class Foo {" + PMD.EOL +
334     "  public <T extends E> Foo() {}" + PMD.EOL +
335     "}";
336 }