RepeatingTypeAnnotations.java revision 2453:3dfd962149b2
1/*
2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 8005220
27 * @summary javap must display repeating annotations
28 */
29import java.io.*;
30import java.util.*;
31
32/**
33 * This class extends the abstract {@link Tester} test-driver, and
34 * encapusulates a number of test-case classes (i.e. classes extending
35 * this class and annotated with {@code TestCase}).
36 * <p>
37 * By default (no argument), this test runs all test-cases, except
38 * if annotated with {@code ignore}.
39 * <p>
40 * Individual test cases can be executed using a run action.
41 * <p>
42 * Example: @run main RepeatingTypeAnnotations RepeatingTypeAnnotations$TC4
43 * <p>
44 * Note: when specific test-cases are run, additional debug output is
45 * produced to help debugging. Test annotated with {@code ignore}
46 * can be executed explicitly.
47 */
48public class RepeatingTypeAnnotations extends Tester {
49
50    /**
51     * Main method instantiates test and run test-cases.
52     */
53    public static void main(String... args) throws Exception {
54        Tester tester = new RepeatingTypeAnnotations();
55        tester.run(args);
56    }
57
58    /**
59     * Testcases are classes extending {@code RepeatingTypeAnnotations},
60     * and calling {@link setSrc}, followed by one or more invocations
61     * of {@link verify} in the body of the constructor.
62     */
63    public RepeatingTypeAnnotations() {
64        setSrc(new TestSource(template));
65    }
66
67    /**
68     * Common template for test cases. The line TESTCASE is
69     * replaced with the specific lines of individual tests.
70     */
71    private static final String[] template = {
72        "import java.lang.annotation.*;",
73        "class Test {",
74        "    @Repeatable(As.class)",
75        "    @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})",
76        "    @Retention(RetentionPolicy.CLASS)",
77        "    @interface A {",
78        "        Class f() default int.class;",
79        "    }",
80
81        "    @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})",
82        "    @Retention(RetentionPolicy.CLASS)",
83        "    @interface As { A[] value(); }",
84
85        "    @Repeatable(Bs.class)",
86        "    @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})",
87        "    @Retention(RetentionPolicy.CLASS)",
88        "    @interface B {",
89        "        Class f() default int.class;",
90        "    }",
91
92        "    @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})",
93        "    @Retention(RetentionPolicy.CLASS)",
94        "    @interface Bs { B[] value(); }",
95
96        "    @Repeatable(Cs.class)",
97        "    @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})",
98        "    @Retention(RetentionPolicy.RUNTIME)",
99        "    @interface C {",
100        "        Class f() default int.class;",
101        "    }",
102
103        "    @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})",
104        "    @Retention(RetentionPolicy.RUNTIME)",
105        "    @interface Cs { C[] value(); }",
106        "TESTCASE",
107        "}"
108    };
109
110    /*
111     * The test cases covers annotation in the following locations:
112     * - static and non-static fields
113     * - local variables
114     * - constructor and method return type and parameter types
115     * - casts in class and method contexts.
116     * For the above locations the test-cases covers:
117     * - single annotation type
118     * - two annotation types with same retention
119     * - two annotation types with different retention
120     * - three annotation types, two of same retention, one different.
121     */
122
123    @TestCase
124    public static class TC1 extends RepeatingTypeAnnotations {
125        public TC1() {
126            setSrc(" /* TC1 */ ",
127                   "    static String so = \"hello world\";",
128                   "    public @A @A @A Object o = (@A @A @A String) Test.so;");
129            verify("RuntimeInvisibleTypeAnnotations",
130                   "0: #25(#26=[@#27(),@#27(),@#27()]): FIELD",
131                   "0: #25(#26=[@#27(),@#27(),@#27()]): CAST, offset=5, type_index=0");
132        }
133    }
134
135    @TestCase
136    public static class TC2 extends RepeatingTypeAnnotations {
137        public TC2() {
138            setSrc(" /* TC2 */ ",
139                   "    static String so = \"hello world\";",
140                   "    public @A @B @A Object o = (@B @A @B String) Test.so;");
141            verify("RuntimeInvisibleTypeAnnotations",
142                   "0: #25(#26=[@#27(),@#27()]): FIELD",
143                   "1: #28(): FIELD",
144                   "0: #36(#26=[@#28(),@#28()]): CAST, offset=5, type_index=0",
145                   "1: #27(): CAST, offset=5, type_index=0");
146        }
147    }
148
149    @TestCase
150    public static class TC3 extends RepeatingTypeAnnotations {
151        public TC3() {
152            setSrc(" /* TC3 */ ",
153                   "    static String so = \"hello world\";",
154                   "    public @A @A @C Object o = (@B @C @B String) Test.so;");
155            verify("RuntimeVisibleTypeAnnotations",
156                   "RuntimeInvisibleTypeAnnotations",
157                   "0: #25(): FIELD",
158                   "0: #27(#28=[@#29(),@#29()]): FIELD",
159                   "0: #25(): CAST, offset=5, type_index=0",
160                   "0: #37(#28=[@#38(),@#38()]): CAST, offset=5, type_index=0");
161        }
162    }
163
164    @TestCase
165    public static class TC4 extends RepeatingTypeAnnotations {
166        public TC4() {
167            setSrc(" /* TC4 */ ",
168                   "    static String so = \"hello world\";",
169                   "    public @A @B @C Object o = (@C @B @A String) Test.so;");
170            verify("RuntimeInvisibleTypeAnnotations",
171                   "RuntimeVisibleTypeAnnotations",
172                   "0: #25(): FIELD",
173                   "0: #27(): FIELD",
174                   "1: #28(): FIELD",
175                   "0: #25(): CAST, offset=5, type_index=0",
176                   "0: #28(): CAST, offset=5, type_index=0",
177                   "1: #27(): CAST, offset=5, type_index=0");
178        }
179    }
180
181    @TestCase
182    public static class TC5 extends RepeatingTypeAnnotations {
183        public TC5() {
184            setSrc(" /* TC5 */ ",
185                   "    static String so = \"hello world\";",
186                   "    public static @A @A @A Object o = (@B @B @B String) Test.so;");
187            verify("RuntimeInvisibleTypeAnnotations",
188                   "0: #25(#26=[@#27(),@#27(),@#27()]): FIELD",
189                   "0: #36(#26=[@#37(),@#37(),@#37()]): CAST, offset=5, type_index=0");
190        }
191    }
192
193    @TestCase
194    public static class TC6 extends RepeatingTypeAnnotations {
195        public TC6() {
196            setSrc(" /* TC6 */ ",
197                   "    static String so = \"hello world\";",
198                   "    public static @A @B @A Object o = (@B @A @B String) Test.so;");
199            verify("RuntimeInvisibleTypeAnnotations",
200                   "0: #25(#26=[@#27(),@#27()]): FIELD",
201                   "1: #28(): FIELD",
202                   "0: #37(#26=[@#28(),@#28()]): CAST, offset=5, type_index=0",
203                   "1: #27(): CAST, offset=5, type_index=0");
204        }
205    }
206
207    @TestCase
208    public static class TC7 extends RepeatingTypeAnnotations {
209        public TC7() {
210            setSrc(" /* TC7 */ ",
211                   "    static String so = \"hello world\";",
212                   "    public static @A @A @C Object o = (@B @C @B String) Test.so;");
213            verify("RuntimeVisibleTypeAnnotations",
214                   "RuntimeInvisibleTypeAnnotations",
215                   "0: #25(): FIELD",
216                   "0: #27(#28=[@#29(),@#29()]): FIELD",
217                   "0: #25(): CAST, offset=5, type_index=0",
218                   "0: #38(#28=[@#39(),@#39()]): CAST, offset=5, type_index=0");
219        }
220    }
221
222    @TestCase
223    public static class TC8 extends RepeatingTypeAnnotations {
224        public TC8() {
225            setSrc(" /* TC8 */ ",
226                   "    static String so = \"hello world\";",
227                   "    public static @A @B @C Object o = (@C @B @A String) Test.so;");
228
229            verify("RuntimeVisibleTypeAnnotations",
230                   "RuntimeInvisibleTypeAnnotations",
231                   "0: #25(): FIELD",
232                   "0: #27(): FIELD",
233                   "1: #28(): FIELD",
234                   "0: #25(): CAST, offset=5, type_index=0",
235                   "0: #28(): CAST, offset=5, type_index=0",
236                   "1: #27(): CAST, offset=5, type_index=0");
237        }
238    }
239
240    @TestCase
241    public static class TC9 extends RepeatingTypeAnnotations {
242        public TC9() {
243            setSrc(" /* TC9 */ ",
244                   "    public Test(@A @A @A Object o, @A int i, long l) {",
245                   "        @A @A @A String ls = (@B @B @B String) o;",
246                   "    }");
247            verify("RuntimeInvisibleTypeAnnotations",
248                   "0: #34(#35=[@#36(),@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
249                   "1: #37(#35=[@#38(),@#38(),@#38()]): CAST, offset=4, type_index=0",
250                   "RuntimeInvisibleTypeAnnotations",
251                   "0: #36(): METHOD_FORMAL_PARAMETER, param_index=1",
252                   "1: #34(#35=[@#36(),@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0");
253        }
254    }
255
256    @TestCase
257    public static class TC10 extends RepeatingTypeAnnotations {
258        public TC10() {
259            setSrc(" /* TC10 */ ",
260                   "    public Test(@A @A @B Object o, @A @B int i, long l) {",
261                   "        @A @A @B String ls = (@B @A @B String) o;",
262                   "    }");
263            verify("RuntimeInvisibleTypeAnnotations",
264                   "0: #34(#35=[@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
265                   "1: #37(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
266                   "2: #38(#35=[@#37(),@#37()]): CAST, offset=4, type_index=0",
267                   "3: #36(): CAST, offset=4, type_index=0",
268                   "RuntimeInvisibleTypeAnnotations",
269                   "0: #36(): METHOD_FORMAL_PARAMETER, param_index=1",
270                   "1: #37(): METHOD_FORMAL_PARAMETER, param_index=1",
271                   "2: #34(#35=[@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0",
272                   "3: #37(): METHOD_FORMAL_PARAMETER, param_index=0");
273        }
274    }
275
276    @TestCase
277    public static class TC11 extends RepeatingTypeAnnotations {
278        public TC11() {
279            setSrc(" /* TC11 */ ",
280                   "    public Test(@C @C @A Object o, @A @B int i, long l) {",
281                   "        @C @C @A String ls = (@A @A @C String) o;",
282                   "    }");
283            verify("RuntimeVisibleTypeAnnotations",
284                   "RuntimeInvisibleTypeAnnotations",
285                   "0: #34(#35=[@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
286                   "1: #36(): CAST, offset=4, type_index=0",
287                   "0: #38(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
288                   "1: #39(#35=[@#38(),@#38()]): CAST, offset=4, type_index=0",
289                   "0: #34(#35=[@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0",
290                   "0: #38(): METHOD_FORMAL_PARAMETER, param_index=1",
291                   "1: #40(): METHOD_FORMAL_PARAMETER, param_index=1",
292                   "2: #38(): METHOD_FORMAL_PARAMETER, param_index=0");
293        }
294    }
295
296    @TestCase
297    public static class TC12 extends RepeatingTypeAnnotations {
298        public TC12() {
299            setSrc(" /* TC12 */ ",
300                   "    public Test(@A @B @C Object o, @A @C int i, long l) {",
301                   "        @A @B @C String ls = (@C @A @B String) o;",
302                   "    }");
303            verify("RuntimeVisibleTypeAnnotations",
304                   "0: #34(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
305                   "1: #34(): CAST, offset=4, type_index=0",
306                   "RuntimeInvisibleTypeAnnotations",
307                   "0: #36(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
308                   "1: #37(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
309                   "2: #36(): CAST, offset=4, type_index=0",
310                   "3: #37(): CAST, offset=4, type_index=0",
311                   "0: #34(): METHOD_FORMAL_PARAMETER, param_index=0",
312                   "1: #34(): METHOD_FORMAL_PARAMETER, param_index=1",
313                   "0: #36(): METHOD_FORMAL_PARAMETER, param_index=0",
314                   "1: #37(): METHOD_FORMAL_PARAMETER, param_index=0",
315                   "2: #36(): METHOD_FORMAL_PARAMETER, param_index=1");
316        }
317    }
318
319    @TestCase
320    public static class TC13 extends RepeatingTypeAnnotations {
321        public TC13() {
322            setSrc(" /* TC13 */ ",
323                   "    public @A @A @A String foo(@A @A @A Object o, @A int i, long l) {",
324                   "        @A @A @A String ls = (@B @B @B String) o;",
325                   "        return (@A @A @A String) o;",
326                   "    }");
327            verify("RuntimeInvisibleTypeAnnotations",
328                   "0: #36(#37=[@#38(),@#38(),@#38()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
329                   "1: #39(#37=[@#40(),@#40(),@#40()]): CAST, offset=0, type_index=0",
330                   "2: #36(#37=[@#38(),@#38(),@#38()]): CAST, offset=6, type_index=0",
331                    "RuntimeInvisibleTypeAnnotations",
332                   "0: #38(): METHOD_FORMAL_PARAMETER, param_index=1",
333                   "1: #36(#37=[@#38(),@#38(),@#38()]): METHOD_FORMAL_PARAMETER, param_index=0",
334                   "2: #36(#37=[@#38(),@#38(),@#38()]): METHOD_RETURN"
335                   );
336        }
337    }
338
339    @TestCase
340    public static class TC14 extends RepeatingTypeAnnotations {
341        public TC14() {
342            setSrc(" /* TC14 */ ",
343                   "    public @A @B @B String foo(@A @A @B Object o, @A @B int i, long l) {",
344                   "        @A @A @B String ls = (@B @A @B String) o;",
345                   "        return (@A @B @B String) o;",
346                   "    }");
347           verify(
348                    "RuntimeInvisibleTypeAnnotations:",
349                  "0: #36(#37=[@#38(),@#38()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
350                  "1: #39(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
351                  "2: #40(#37=[@#39(),@#39()]): CAST, offset=0, type_index=0",
352                  "3: #38(): CAST, offset=0, type_index=0",
353                  "4: #38(): CAST, offset=6, type_index=0",
354                  "5: #40(#37=[@#39(),@#39()]): CAST, offset=6, type_index=0",
355                    "RuntimeInvisibleTypeAnnotations:",
356                  "0: #38(): METHOD_FORMAL_PARAMETER, param_index=1",
357                  "1: #39(): METHOD_FORMAL_PARAMETER, param_index=1",
358                  "2: #36(#37=[@#38(),@#38()]): METHOD_FORMAL_PARAMETER, param_index=0",
359                  "3: #39(): METHOD_FORMAL_PARAMETER, param_index=0",
360                  "4: #38(): METHOD_RETURN",
361                  "5: #40(#37=[@#39(),@#39()]): METHOD_RETURN"
362                 );
363        }
364    }
365
366    @TestCase
367    public static class TC15 extends RepeatingTypeAnnotations {
368        public TC15() {
369            setSrc(" /* TC15 */ ",
370                   "    public @A @A @C String foo(@C @C @A Object o, @A @B int i, long l) {",
371                   "        @C @C @A String ls = (@A @A @C String) o;",
372                   "        return (@C @B @B String) o;",
373                   "    }");
374            verify(
375                    "RuntimeVisibleTypeAnnotations:",
376                   "0: #36(#37=[@#38(),@#38()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
377                   "1: #38(): CAST, offset=0, type_index=0",
378                   "2: #38(): CAST, offset=6, type_index=0",
379                    "RuntimeInvisibleTypeAnnotations:",
380                   "0: #40(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
381                   "1: #41(#37=[@#40(),@#40()]): CAST, offset=0, type_index=0",
382                   "2: #42(#37=[@#43(),@#43()]): CAST, offset=6, type_index=0",
383                    "RuntimeVisibleTypeAnnotations:",
384                   "0: #36(#37=[@#38(),@#38()]): METHOD_FORMAL_PARAMETER, param_index=0",
385                   "1: #38(): METHOD_RETURN",
386                    "RuntimeInvisibleTypeAnnotations:",
387                   "0: #40(): METHOD_FORMAL_PARAMETER, param_index=1",
388                   "1: #43(): METHOD_FORMAL_PARAMETER, param_index=1",
389                   "2: #40(): METHOD_FORMAL_PARAMETER, param_index=0",
390                   "3: #41(#37=[@#40(),@#40()]): METHOD_RETURN"
391                    );
392        }
393    }
394
395    @TestCase
396    public static class TC16 extends RepeatingTypeAnnotations {
397        public TC16() {
398            setSrc(" /* TC16 */ ",
399                   "    public @A @B @C String foo(@A @B @C Object o, @A @C int i, long l) {",
400                   "        @A @B @C String ls = (@C @A @B String) o;",
401                   "        return (@B @A @C String) o;",
402                   "    }");
403            verify(
404                    "RuntimeVisibleTypeAnnotations:",
405                   "0: #36(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
406                   "1: #36(): CAST, offset=0, type_index=0",
407                   "2: #36(): CAST, offset=6, type_index=0",
408                    "RuntimeInvisibleTypeAnnotations:",
409                   "0: #38(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
410                   "1: #39(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
411                   "2: #38(): CAST, offset=0, type_index=0",
412                   "3: #39(): CAST, offset=0, type_index=0",
413                   "4: #39(): CAST, offset=6, type_index=0",
414                   "5: #38(): CAST, offset=6, type_index=0",
415                    "RuntimeVisibleTypeAnnotations:",
416                   "0: #36(): METHOD_FORMAL_PARAMETER, param_index=0",
417                   "1: #36(): METHOD_FORMAL_PARAMETER, param_index=1",
418                   "2: #36(): METHOD_RETURN",
419                    "RuntimeInvisibleTypeAnnotations:",
420                   "0: #38(): METHOD_FORMAL_PARAMETER, param_index=0",
421                   "1: #39(): METHOD_FORMAL_PARAMETER, param_index=0",
422                   "2: #38(): METHOD_FORMAL_PARAMETER, param_index=1",
423                   "3: #38(): METHOD_RETURN",
424                   "4: #39(): METHOD_RETURN"
425                  );
426        }
427    }
428}
429