test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java

Tue, 14 May 2013 15:04:06 -0700

author
jjg
date
Tue, 14 May 2013 15:04:06 -0700
changeset 1755
ddb4a2bfcd82
parent 1721
abd153854f16
child 1969
7de231613e4a
permissions
-rw-r--r--

8013852: update reference impl for type-annotations
Reviewed-by: jjg
Contributed-by: wdietl@gmail.com, steve.sides@oracle.com, joel.franck@oracle.com, alex.buckley@oracle.com

     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  */
    24 /*
    25  * @test
    26  * @bug 8005085 8005877 8004829 8005681 8006734 8006775 8006507
    27  * @summary Combinations of Target ElementTypes on (repeated)type annotations.
    28  */
    30 import com.sun.tools.classfile.*;
    31 import java.io.File;
    33 public class CombinationsTargetTest2 extends ClassfileTestHelper {
    35     // Test count helps identify test case in event of failure.
    36     int testcount = 0;
    38     // Base test case template descriptions
    39     enum srce  {
    40         src1("(repeating) type annotations on on field in method body",true),
    41         src2("(repeating) type annotations on type parameters, bounds and  type arguments", true),
    42         src3("(repeating) type annotations on type parameters of class, method return value in method", true),
    43         src4("(repeating) type annotations on field in anonymous class", false),
    44         src5("(repeating) type annotations on field in anonymous class", false);
    46         String description;
    47         Boolean local;
    49         srce(String desc, Boolean b) {
    50             this.description = this + ": " +desc;
    51             this.local = b;
    52         }
    53     }
    56     String[] ETypes={"TYPE", "FIELD", "METHOD", "PARAMETER", "CONSTRUCTOR",
    57                      "LOCAL_VARIABLE", "ANNOTATION_TYPE", "PACKAGE"};
    59     // local class tests will have an inner class.
    60     Boolean hasInnerClass=false;
    61     String innerClassname="";
    63     public static void main(String[] args) throws Exception {
    64         new CombinationsTargetTest2().run();
    65     }
    67     void run() throws Exception {
    68         // Determines which repeat and order in source(ABMix).
    69         Boolean As= false, BDs=true, ABMix=false;
    70         int testrun=0;
    71         Boolean [][] bRepeat = new Boolean[][]{{false,false,false},//no repeats
    72                                                {true,false,false}, //repeat @A
    73                                                {false,true,false}, //repeat @B
    74                                                {true,true,false},  //repeat both
    75                                                {false,false,true}  //repeat mix
    76         };
    78         for(Boolean[] bCombo : bRepeat) {
    79             As=bCombo[0]; BDs=bCombo[1]; ABMix=bCombo[2];
    80             for(String et : ETypes) {
    81                switch(et) {
    82                    case "METHOD":
    83                        test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src1);
    84                        test( 0, 8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1);
    85                        test( 2, 0, 2, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src5);
    86                        test( 0, 2, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src5);
    87                        break;
    88                    case "FIELD":
    89                        test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src1);
    90                        test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src2);
    91                        test( 6, 0, 0, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src3);
    92                        test( 2, 0, 2, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src4);
    93                        test( 0, 8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1);
    94                        test( 0, 8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src2);
    95                        test( 0, 6, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src3);
    96                        test( 0, 2, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src4);
    97                        break;
    98                    default:/*TYPE,PARAMETER,LOCAL_VARIABLE,ANNOTATION_TYPE,PACKAGE*/
    99                        test( 0, 2, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src4);
   100                        test( 0, 2, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src5);
   101                        break;
   102                }
   103             }
   104         }
   105     }
   107     public void test(int tinv, int tvis, int inv, int vis, Boolean Arepeats,
   108                      Boolean BDrepeats, Boolean ABmix, String rtn, String et2,
   109                      Integer N, srce source) throws Exception {
   110         ++testcount;
   111         expected_tvisibles = tvis;
   112         expected_tinvisibles = tinv;
   113         expected_visibles = vis;
   114         expected_invisibles = inv;
   115         File testFile = null;
   116         String tname="Test" + N.toString();
   117         hasInnerClass=false;
   118         String testDef = "Test " + testcount + " parameters: tinv=" + tinv +
   119                 ", tvis=" + tvis + ", inv=" + inv + ", vis=" + vis +
   120                 ", Arepeats=" + Arepeats + ", BDrepeats=" + BDrepeats +
   121                 ", ABmix=" + ABmix + ", retention: " + rtn + ", anno2: " +
   122                 et2 + ", src=" + source + "\n    " + source.description;
   124         if(
   125 // 8005681 - src1,2,3 - skip cases with repeated annotations on new, array, cast.
   126             (( source.equals(srce.src1) || source.equals(srce.src2) ||
   127               source.equals(srce.src3)) && (ABmix || (Arepeats && BDrepeats)))
   128  // 8008928 - src4,5 - this change cause crash with t-a on anon class)
   129             || (source.equals(srce.src4) || source.equals(srce.src5))
   130           ) {
   131             System.out.println(testDef +
   132                        "\n    8005681-skip repeated annotations on new,array,cast");
   133             return;
   134         }
   136         println(testDef);
   137         // Create test source and File.
   138         String sourceString = sourceString(tname, rtn, et2, Arepeats,
   139                                            BDrepeats, ABmix, source);
   140         testFile = writeTestFile(tname+".java", sourceString);
   141         // Compile test source and read classfile.
   142         File classFile = null;
   143         try {
   144             classFile = compile(testFile);
   145         } catch (Error err) {
   146             System.err.println("Failed compile. Source:\n" + sourceString);
   147             throw err;
   148         }
   149         //if sourcString() set hasInnerClass it also set innerClassname.
   150         if(hasInnerClass) {
   151             StringBuffer sb = new StringBuffer(classFile.getAbsolutePath());
   152             classFile=new File(sb.insert(sb.lastIndexOf(".class"),innerClassname).toString());
   153             println("classfile: " + classFile.getAbsolutePath());
   154         }
   155         ClassFile cf = ClassFile.read(classFile);
   157         //Test class,fields and method counts.
   158         test(cf);
   160         for (Field f : cf.fields) {
   161             if(source.local)
   162                 test(cf, f, true);
   163             else
   164                 test(cf,f);
   165         }
   166         for (Method m: cf.methods) {
   167             if(source.local)
   168                 test(cf, m, true);
   169             else
   170                 test(cf, m);
   171         }
   172         countAnnotations();
   173         if (errors > 0) {
   174             System.err.println( testDef );
   175             System.err.println( "Source:\n" + sourceString );
   176             throw new Exception( errors + " errors found" );
   177         }
   178         println("Pass");
   179     }
   181     //
   182     // Source for test cases
   183     //
   184     String sourceString(String testname, String retentn, String annot2,
   185                         Boolean Arepeats, Boolean BDrepeats, Boolean ABmix,
   186                         srce src) {
   188         String As = "@A", Bs = "@B", Ds = "@D";
   189         if(Arepeats) As = "@A @A";
   190         if(BDrepeats) {
   191             Bs = "@B @B";
   192             Ds = "@D @D";
   193         }
   194         if(ABmix) { As = "@A @B"; Bs = "@A @B"; Ds = "@D @D"; }
   196         // Source to check for TYPE_USE and TYPE_PARAMETER annotations.
   197         // Source base (annotations) is same for all test cases.
   198         String source = new String();
   199         String imports = new String("import java.lang.annotation.*; \n" +
   200             "import static java.lang.annotation.RetentionPolicy.*; \n" +
   201             "import static java.lang.annotation.ElementType.*; \n" +
   202             "import java.util.List; \n" +
   203             "import java.util.HashMap; \n" +
   204             "import java.util.Map; \n\n");
   206             String sourceBase = new String("@Retention("+retentn+")\n" +
   207             "@Target({TYPE_USE,_OTHER_})\n" +
   208             "@Repeatable( AC.class )\n" +
   209             "@interface A { }\n\n" +
   211             "@Retention("+retentn+")\n" +
   212             "@Target({TYPE_USE,_OTHER_})\n" +
   213             "@interface AC { A[] value(); }\n\n" +
   215             "@Retention("+retentn+")\n" +
   216             "@Target({TYPE_USE,_OTHER_})\n" +
   217             "@Repeatable( BC.class )\n" +
   218             "@interface B { }\n\n" +
   220             "@Retention("+retentn+")\n" +
   221             "@Target({TYPE_USE,_OTHER_})\n" +
   222             "@interface BC { B[] value(); } \n\n" +
   224             "@Retention("+retentn+")\n" +
   225             "@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" +
   226             "@Repeatable(DC.class)\n" +
   227             "@interface D { }\n\n" +
   229             "@Retention("+retentn+")\n" +
   230             "@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" +
   231             "@interface DC { D[] value(); }\n\n");
   233         // Test case sources with sample generated source
   234         switch(src) {
   235             case src1: // (repeating) type annotations on field in method body
   236                     /*
   237                      * class Test1 {
   238                      * Test1(){}
   239                      * // type usage in method body
   240                      * String test(Test1 this, String param, String ... vararg) {
   241                      *     @A @B
   242                      *     Object o = new @A @B  String @A @B  [3];
   243                      *         return (@A @B  String) null;
   244                      * }}
   245                       */
   246                 source = new String(
   247                     "// " + src.description + "\n" +
   248                     "class " + testname + " {\n" +
   249                     "" + testname +"(){} \n" +
   250                     "// type usage in method body \n" +
   251                     "String test("+testname+" this, " +
   252                        "String param, String ... vararg) { \n" +
   253                     "    _As_ _Bs_\n    Object o = new _As_ _Bs_  String _As_ _Bs_  [3]; \n" +
   254                     "        return (_As_ _Bs_  String) null; \n" +
   255                     "} \n" +
   256                     "} \n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
   257                     "\n\n";
   258                     break;
   259             case src2: // (repeating) annotations on type parameters, bounds and  type arguments in new statement.
   260                     /*
   261                      * class Test2<T extends Object> {
   262                      *     Map<List<String>, Integer> map =
   263                      *         new HashMap<@A @B List<@A @B String>, @A @B Integer>();
   264                      *     Map<List<String>, Integer> map2 = new @A @B HashMap<>();
   265                      *     String test(Test2<T> this) { return null;}
   266                      *     <T> String genericMethod(T t) { return null; }
   267                      * }
   268                      */
   269                 source = new String( source +
   270                     "// " + src.description + "\n" +
   271                     "class " + testname + "<T extends Object> {\n" +
   272                     "    Map<List<String>, Integer> map =\n" +
   273                     "        new HashMap<_As_ _Bs_ List<_As_ _Bs_ String>, _As_ _Bs_ Integer>();\n" +
   274                     "    Map<List<String>, Integer> map2 = new _As_ _Bs_ HashMap<>();\n" +
   275                     "    String test(" + testname + "<T> this) { return null;}\n" +
   276                     "    <T> String genericMethod(T t) { return null; }\n" +
   277                     "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
   278                     "\n\n";
   279                 break;
   280             case src3: // (repeating)annotations on type parameters of class, method return value in method.
   281                     /*
   282                      * class Test3{
   283                      *     <E extends Comparable> Map<List<E>, E > foo(E e) {
   284                      *         class maptest <E> {
   285                      *             Map<List<E>,E> getMap() {
   286                      *                 Map<List<E>,E> Em = new HashMap<List<@A @B @D E>,@A @B @D E>();
   287                      *                 return Em;
   288                      *             }
   289                      *         }
   290                      *         return new maptest<E>().getMap();
   291                      *    }
   292                      *    Map<List<String>,String> shm = foo(new String("hello"));
   293                      * }
   294                      */
   295                 source = new String( source +
   296                     "// " + src.description + "\n" +
   297                     "class "+ testname + "{\n" +
   298                     "    <E extends Comparable> Map<List<E>, E > foo(E e) {\n" +
   299                     "        class maptest <E> {\n" +                  // inner class $1maptest
   300                     "            Map<List<E>,E> getMap() { \n" +
   301                     "                Map<List<E>,E> Em = new HashMap<List<_As_ _Bs_ _Ds_ E>,_As_ _Bs_ _Ds_ E>();\n" +
   302                     "                return Em;\n" +
   303                     "            }\n" +
   304                     "        }\n" +
   305                     "        return new maptest<E>().getMap();\n" +
   306                     "   }\n" +
   307                     "   Map<List<String>,String> shm = foo(new String(\"hello\"));\n" +
   308                     "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
   309                     "\n\n";
   310                     hasInnerClass=true;
   311                     innerClassname="$1maptest";
   312                 break;
   313             case src4: // (repeating)annotations on field in anonymous class
   314                     /*
   315                      * class Test95{
   316                      *     void mtest( Test95 t){  }
   317                      *     public void test() {
   318                      *         mtest( new Test95() {
   319                      *             @A @A @B @B String data2 = "test";
   320                      *         });
   321                      *     }
   322                      * }
   323                      */
   324                 source = new String( source +
   325                     "// " + src.description + "\n" +
   326                     "class "+ testname + "{\n" +
   327                     "    void mtest( "+ testname + " t){  }\n" +
   328                     "    public void test() {\n" +
   329                     "        mtest( new "+ testname + "() {\n" +
   330                     "            _As_ _Bs_ String data2 = \"test\";\n" +
   331                     "        });\n" +
   332                     "    }\n" +
   333                     "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
   334                     "\n\n";
   335                     hasInnerClass=true;
   336                     innerClassname="$1";
   337                 break;
   338             case src5: // (repeating)annotations on method in anonymous class
   339                     /*
   340                      * class Test120{
   341                      *     void mtest( Test120 t){  }
   342                      *     public void test() {
   343                      *         mtest( new Test120() {
   344                      *             @A @B @A @B String m2(){return null;};
   345                      *         });
   346                      *     }
   347                      */
   348                 source = new String( source +
   349                     "// " + src.description + "\n" +
   350                     "class "+ testname + "{\n" +
   351                     "    void mtest( "+ testname + " t){  }\n" +
   352                     "    public void test() {\n" +
   353                     "        mtest( new "+ testname + "() {\n" +
   354                     "            _As_ _Bs_ String m2(){return null;};\n" +
   355                     "        });\n" +
   356                     "    }\n" +
   357                     "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
   358                     "\n\n";
   359                     hasInnerClass=true;
   360                     innerClassname="$1";
   361                 break;
   362         }
   363         return imports + source;
   364     }
   365 }

mercurial