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  */
  29 import java.io.*;
  30 import 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  */
  48 public 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 }