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     @ignore // 8008082:missing type annotation for cast
 125     public static class TC1 extends RepeatingTypeAnnotations {
 126         public TC1() {
 127             setSrc(" /* TC1 */ ",
 128                    "    static String so = \"hello world\";",
 129                    "    public @A @A @A Object o = (@A @A @A String) Test.so;");
 130             verify("RuntimeInvisibleTypeAnnotations",
 131                    "0: #25(#26=[@#27(),@#27(),@#27()]): FIELD",
 132                    "1: #25(#26=[@#27(),@#27(),@#27()]): CAST, offset=5");
 133         }
 134     }
 135 
 136     @TestCase
 137     public static class TC2 extends RepeatingTypeAnnotations {
 138         public TC2() {
 139             setSrc(" /* TC2 */ ",
 140                    "    static String so = \"hello world\";",
 141                    "    public @A @B @A Object o = (@B @A @B String) Test.so;");
 142             verify("RuntimeInvisibleTypeAnnotations",
 143                    "0: #25(#26=[@#27(),@#27()]): FIELD",
 144                    "1: #28(): FIELD",
 145                    "0: #36(#26=[@#28(),@#28()]): CAST, offset=5, type_index=0",
 146                    "1: #27(): CAST, offset=5, type_index=0");
 147         }
 148     }
 149 
 150     @TestCase
 151     public static class TC3 extends RepeatingTypeAnnotations {
 152         public TC3() {
 153             setSrc(" /* TC3 */ ",
 154                    "    static String so = \"hello world\";",
 155                    "    public @A @A @C Object o = (@B @C @B String) Test.so;");
 156             verify("RuntimeVisibleTypeAnnotations",
 157                    "RuntimeInvisibleTypeAnnotations",
 158                    "0: #25(): FIELD",
 159                    "0: #27(#28=[@#29(),@#29()]): FIELD",
 160                    "0: #25(): CAST, offset=5, type_index=0",
 161                    "0: #37(#28=[@#38(),@#38()]): CAST, offset=5, type_index=0");
 162         }
 163     }
 164 
 165     @TestCase
 166     public static class TC4 extends RepeatingTypeAnnotations {
 167         public TC4() {
 168             setSrc(" /* TC4 */ ",
 169                    "    static String so = \"hello world\";",
 170                    "    public @A @B @C Object o = (@C @B @A String) Test.so;");
 171             verify("RuntimeInvisibleTypeAnnotations",
 172                    "RuntimeVisibleTypeAnnotations",
 173                    "0: #25(): FIELD",
 174                    "0: #27(): FIELD",
 175                    "1: #28(): FIELD",
 176                    "0: #25(): CAST, offset=5, type_index=0",
 177                    "0: #28(): CAST, offset=5, type_index=0",
 178                    "1: #27(): CAST, offset=5, type_index=0");
 179         }
 180     }
 181 
 182     @TestCase
 183     @ignore // 8008082:missing type annotation for cast
 184     public static class TC5 extends RepeatingTypeAnnotations {
 185         public TC5() {
 186             setSrc(" /* TC5 */ ",
 187                    "    static String so = \"hello world\";",
 188                    "    public static @A @A @A Object o = (@B @B @B String) Test.so;");
 189             verify("RuntimeInvisibleTypeAnnotations",
 190                    "0: #25(#26=[@#27(),@#27(),@#27()]): FIELD",
 191                    "1: #28(#26=[@#29(),@#29(),@#29()]): CAST, offset=5, type_index=0");
 192         }
 193     }
 194 
 195     @TestCase
 196     public static class TC6 extends RepeatingTypeAnnotations {
 197         public TC6() {
 198             setSrc(" /* TC6 */ ",
 199                    "    static String so = \"hello world\";",
 200                    "    public static @A @B @A Object o = (@B @A @B String) Test.so;");
 201             verify("RuntimeInvisibleTypeAnnotations",
 202                    "0: #25(#26=[@#27(),@#27()]): FIELD",
 203                    "1: #28(): FIELD",
 204                    "0: #37(#26=[@#28(),@#28()]): CAST, offset=5, type_index=0",
 205                    "1: #27(): CAST, offset=5, type_index=0");
 206         }
 207     }
 208 
 209     @TestCase
 210     public static class TC7 extends RepeatingTypeAnnotations {
 211         public TC7() {
 212             setSrc(" /* TC7 */ ",
 213                    "    static String so = \"hello world\";",
 214                    "    public static @A @A @C Object o = (@B @C @B String) Test.so;");
 215             verify("RuntimeVisibleTypeAnnotations",
 216                    "RuntimeInvisibleTypeAnnotations",
 217                    "0: #25(): FIELD",
 218                    "0: #27(#28=[@#29(),@#29()]): FIELD",
 219                    "0: #25(): CAST, offset=5, type_index=0",
 220                    "0: #38(#28=[@#39(),@#39()]): CAST, offset=5, type_index=0");
 221         }
 222     }
 223 
 224     @TestCase
 225     public static class TC8 extends RepeatingTypeAnnotations {
 226         public TC8() {
 227             setSrc(" /* TC8 */ ",
 228                    "    static String so = \"hello world\";",
 229                    "    public static @A @B @C Object o = (@C @B @A String) Test.so;");
 230                    
 231             verify("RuntimeVisibleTypeAnnotations",
 232                    "RuntimeInvisibleTypeAnnotations",
 233                    "0: #25(): FIELD",
 234                    "0: #27(): FIELD",
 235                    "1: #28(): FIELD",
 236                    "0: #25(): CAST, offset=5, type_index=0",
 237                    "0: #28(): CAST, offset=5, type_index=0",
 238                    "1: #27(): CAST, offset=5, type_index=0");
 239         }
 240     }
 241 
 242     @TestCase
 243     @ignore // 8008082:missing type annotation for cast
 244     public static class TC9 extends RepeatingTypeAnnotations {
 245         public TC9() {
 246             setSrc(" /* TC9 */ ",
 247                    "    public Test(@A @A @A Object o, @A int i, long l) {",
 248                    "        @A @A @A String ls = (@B @B @B String) o;",
 249                    "    }");
 250             verify("RuntimeInvisibleTypeAnnotations",
 251                    "0: #34(#35=[@#36(),@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0",
 252                    "1: #36(): METHOD_FORMAL_PARAMETER, param_index=1",
 253                    "2: #37(#35=[@#38(),@#38(),@#38()]): CAST, offset=4, type_index=0",
 254                    "3: #34(#35=[@#36(),@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}");
 255         }
 256     }
 257 
 258     @TestCase
 259     public static class TC10 extends RepeatingTypeAnnotations {
 260         public TC10() {
 261             setSrc(" /* TC10 */ ",
 262                    "    public Test(@A @A @B Object o, @A @B int i, long l) {",
 263                    "        @A @A @B String ls = (@B @A @B String) o;",
 264                    "    }");
 265             verify("RuntimeInvisibleTypeAnnotations",
 266                    "0: #34(#35=[@#36(),@#36()]): CAST, offset=4, type_index=0",
 267                    "1: #37(): CAST, offset=4, type_index=0",
 268                    "2: #38(#35=[@#37(),@#37()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
 269                    "3: #36(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
 270                    "RuntimeInvisibleTypeAnnotations",
 271                    "0: #38(#35=[@#37(),@#37()]): METHOD_FORMAL_PARAMETER, param_index=0",
 272                    "1: #36(): METHOD_FORMAL_PARAMETER, param_index=0",
 273                    "2: #37(): METHOD_FORMAL_PARAMETER, param_index=1",
 274                    "3: #36(): METHOD_FORMAL_PARAMETER, param_index=1");
 275         }
 276     }
 277 
 278     @TestCase
 279     public static class TC11 extends RepeatingTypeAnnotations {
 280         public TC11() {
 281             setSrc(" /* TC11 */ ",
 282                    "    public Test(@C @C @A Object o, @A @B int i, long l) {",
 283                    "        @C @C @A String ls = (@A @A @C String) o;",
 284                    "    }");
 285             verify("RuntimeVisibleTypeAnnotations",
 286                    "RuntimeInvisibleTypeAnnotations",
 287                    "0: #34(): CAST, offset=4, type_index=0",
 288                    "1: #35(#36=[@#34(),@#34()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
 289                    "0: #38(#36=[@#39(),@#39()]): CAST, offset=4, type_index=0",
 290                    "1: #39(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
 291                    "0: #35(#36=[@#34(),@#34()]): METHOD_FORMAL_PARAMETER, param_index=0",
 292                    "0: #39(): METHOD_FORMAL_PARAMETER, param_index=0",
 293                    "1: #39(): METHOD_FORMAL_PARAMETER, param_index=1",
 294                    "2: #40(): METHOD_FORMAL_PARAMETER, param_index=1");
 295         }
 296     }
 297 
 298     @TestCase
 299     public static class TC12 extends RepeatingTypeAnnotations {
 300         public TC12() {
 301             setSrc(" /* TC12 */ ",
 302                    "    public Test(@A @B @C Object o, @A @C int i, long l) {",
 303                    "        @A @B @C String ls = (@C @A @B String) o;",
 304                    "    }");
 305             verify("RuntimeVisibleTypeAnnotations",
 306                    "0: #34(): CAST, offset=4, type_index=0",
 307                    "1: #34(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
 308                    "RuntimeInvisibleTypeAnnotations",
 309                    "0: #36(): CAST, offset=4, type_index=0",
 310                    "1: #37(): CAST, offset=4, type_index=0",
 311                    "2: #36(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
 312                    "3: #37(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
 313                    "0: #34(): METHOD_FORMAL_PARAMETER, param_index=0",
 314                    "1: #34(): METHOD_FORMAL_PARAMETER, param_index=1",
 315                    "0: #36(): METHOD_FORMAL_PARAMETER, param_index=0",
 316                    "1: #37(): METHOD_FORMAL_PARAMETER, param_index=0",
 317                    "2: #36(): METHOD_FORMAL_PARAMETER, param_index=1");
 318         }
 319     }
 320 
 321     @TestCase
 322     @ignore // 8008082:missing type annotation for cast
 323     public static class TC13 extends RepeatingTypeAnnotations {
 324         public TC13() {
 325             setSrc(" /* TC13 */ ",
 326                    "    public @A @A @A String foo(@A @A @A Object o, @A int i, long l) {",
 327                    "        @A @A @A String ls = (@B @B @B String) o;",
 328                    "        return (@A @A @A String) o;",
 329                    "    }");
 330             verify("RuntimeInvisibleTypeAnnotations",
 331                    "0: #36(#37=[@#38(),@#38(),@#38()]): METHOD_RETURN",
 332                    "1: #36(#37=[@#38(),@#38(),@#38()]): METHOD_FORMAL_PARAMETER, param_index=0",
 333                    "2: #38(): METHOD_FORMAL_PARAMETER, param_index=1",
 334                    "3: #39(#37=[@#40(),@#40(),@#40()]): CAST, offset=0, type_index=0",
 335                    "4: #36(#37=[@#38(),@#38(),@#38()]): CAST, offset=6, type_index=0",
 336                    "5: #36(#37=[@#38(),@#38(),@#38()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}");
 337         }
 338     }
 339 
 340     @TestCase
 341     public static class TC14 extends RepeatingTypeAnnotations {
 342         public TC14() {
 343             setSrc(" /* TC14 */ ",
 344                    "    public @A @B @B String foo(@A @A @B Object o, @A @B int i, long l) {",
 345                    "        @A @A @B String ls = (@B @A @B String) o;",
 346                    "        return (@A @B @B String) o;",
 347                    "    }");
 348            verify("RuntimeInvisibleTypeAnnotations:",
 349                   "0: #36(#37=[@#38(),@#38()]): CAST, offset=0, type_index=0",
 350                   "1: #39(): CAST, offset=0, type_index=0",
 351                   "2: #39(): CAST, offset=6, type_index=0",
 352                   "3: #36(#37=[@#38(),@#38()]): CAST, offset=6, type_index=0",
 353                   "4: #40(#37=[@#39(),@#39()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
 354                   "5: #38(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
 355                   "0: #39(): METHOD_RETURN",
 356                   "1: #36(#37=[@#38(),@#38()]): METHOD_RETURN",
 357                   "2: #40(#37=[@#39(),@#39()]): METHOD_FORMAL_PARAMETER, param_index=0",
 358                   "3: #38(): METHOD_FORMAL_PARAMETER, param_index=0",
 359                   "4: #39(): METHOD_FORMAL_PARAMETER, param_index=1",
 360                   "5: #38(): METHOD_FORMAL_PARAMETER, param_index=1");
 361         }
 362     }
 363 
 364     @TestCase
 365     public static class TC15 extends RepeatingTypeAnnotations {
 366         public TC15() {
 367             setSrc(" /* TC15 */ ",
 368                    "    public @A @A @C String foo(@C @C @A Object o, @A @B int i, long l) {",
 369                    "        @C @C @A String ls = (@A @A @C String) o;",
 370                    "        return (@C @B @B String) o;",
 371                    "    }");
 372             verify("RuntimeVisibleTypeAnnotations",
 373                    "RuntimeInvisibleTypeAnnotations",
 374                    "0: #36(): CAST, offset=0, type_index=0",
 375                    "1: #36(): CAST, offset=6, type_index=0",
 376                    "2: #37(#38=[@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
 377                    "0: #40(#38=[@#41(),@#41()]): CAST, offset=0, type_index=0",
 378                    "1: #42(#38=[@#43(),@#43()]): CAST, offset=6, type_index=0",
 379                    "2: #41(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
 380                    "0: #36(): METHOD_RETURN",
 381                    "1: #37(#38=[@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0",
 382                    "0: #40(#38=[@#41(),@#41()]): METHOD_RETURN",
 383                    "1: #41(): METHOD_FORMAL_PARAMETER, param_index=0",
 384                    "2: #41(): METHOD_FORMAL_PARAMETER, param_index=1",
 385                    "3: #43(): METHOD_FORMAL_PARAMETER, param_index=1");
 386 
 387         }
 388     }
 389 
 390     @TestCase
 391     public static class TC16 extends RepeatingTypeAnnotations {
 392         public TC16() {
 393             setSrc(" /* TC16 */ ",
 394                    "    public @A @B @C String foo(@A @B @C Object o, @A @C int i, long l) {",
 395                    "        @A @B @C String ls = (@C @A @B String) o;",
 396                    "        return (@B @A @C String) o;",
 397                    "    }");
 398             verify("RuntimeVisibleTypeAnnotations",
 399                    "RuntimeInvisibleTypeAnnotations",
 400                    "0: #36(): CAST, offset=0, type_index=0",
 401                    "1: #36(): CAST, offset=6, type_index=0",
 402                    "2: #36(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
 403                    "0: #38(): CAST, offset=0, type_index=0",
 404                    "1: #39(): CAST, offset=0, type_index=0",
 405                    "2: #39(): CAST, offset=6, type_index=0",
 406                    "3: #38(): CAST, offset=6, type_index=0",
 407                    "4: #38(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
 408                    "5: #39(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
 409                    "0: #36(): METHOD_RETURN",
 410                    "1: #36(): METHOD_FORMAL_PARAMETER, param_index=0",
 411                    "2: #36(): METHOD_FORMAL_PARAMETER, param_index=1",
 412                    "0: #38(): METHOD_RETURN",
 413                    "1: #39(): METHOD_RETURN",
 414                    "2: #38(): METHOD_FORMAL_PARAMETER, param_index=0",
 415                    "3: #39(): METHOD_FORMAL_PARAMETER, param_index=0",
 416                    "4: #38(): METHOD_FORMAL_PARAMETER, param_index=1");
 417         }
 418     }
 419 }