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

Wed, 27 Apr 2016 01:34:52 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:34:52 +0800
changeset 0
959103a6100f
child 2525
2eb010b6cb22
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/langtools/
changeset: 2573:53ca196be1ae
tag: jdk8u25-b17

     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
    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 CombinationsTargetTest1 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 at class level"),
    41         src2("(repeating) type annotations on method"),
    42         src3("(repeating) type annotations on wildcard, type arguments in anonymous class"),
    43         src4("(repeating) type annotations on type parameters, bounds and  type arguments on class decl"),
    44         src5("(repeating) type annotations on type parameters, bounds and  type arguments on method"),
    45         src6("(repeating) type annotations on type parameters, bounds and  type arguments in method");
    47         String description;
    49         srce(String desc) {
    50             this.description = this + ": " +desc;
    51         }
    52     }
    54     String[] ETypes={"TYPE", "FIELD", "METHOD", "PARAMETER", "CONSTRUCTOR",
    55                      "LOCAL_VARIABLE", "ANNOTATION_TYPE", "PACKAGE"};
    57     // local class tests will have an inner class.
    58     Boolean hasInnerClass=false;
    59     String innerClassname="";
    61     public static void main(String[] args) throws Exception {
    62         new CombinationsTargetTest1().run();
    63     }
    65     void run() throws Exception {
    66         // Determines which repeat and order in source(ABMix).
    67         Boolean As= false, BDs=true, ABMix=false;
    68         int testrun=0;
    69         Boolean [][] bRepeat = new Boolean[][]{{false,false,false},//no repeats
    70                                                {true,false,false}, //repeat @A
    71                                                {false,true,false}, //repeat @B
    72                                                {true,true,false},  //repeat both
    73                                                {false,false,true}  //repeat mix
    74         };
    75         for(Boolean[] bCombo : bRepeat) {
    76             As=bCombo[0]; BDs=bCombo[1]; ABMix=bCombo[2];
    77             for(String et : ETypes) {
    78                switch(et) {
    79                    case "METHOD":
    80                        test( 8,  0, 2, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src1);
    81                        test(10,  0, 2, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src2);
    82                        test( 6,  0, 0, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src3);
    83                        test(10,  0, 2, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src5);
    84                        test( 0,  8, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1);
    85                        test( 0, 10, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src2);
    86                        test( 0,  6, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src3);
    87                        test( 0, 10, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src5);
    88                        break;
    89                    case "CONSTRUCTOR":
    90                    case "FIELD":
    91                        test( 8,  0, 4, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src1);
    92                        test( 6,  0, 3, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src4);
    93                        test( 9,  0, 0, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src6);
    94                        test( 0,  8, 0, 4, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1);
    95                        test( 0,  6, 0, 3, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src4);
    96                        test( 0,  9, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src6);
    97                        break;
    98                    default:/*TYPE,PARAMETER,LOCAL_VARIABLE,ANNOTATION_TYPE,PACKAGE*/
    99                        test( 8,  0, 2, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src1);
   100                        test( 6,  0, 3, 0, As, BDs, ABMix, "CLASS",   et, ++testrun, srce.src4);
   101                        test( 0,  8, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1);
   102                        test( 0,  6, 0, 3, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src4);
   103                }
   104             }
   105         }
   106     }
   108     public void test(int tinv, int tvis, int inv, int vis, Boolean Arepeats,
   109                      Boolean BDrepeats, Boolean ABmix, String rtn, String et2,
   110                      Integer N, srce source) throws Exception {
   111         ++testcount;
   112         expected_tvisibles = tvis;
   113         expected_tinvisibles = tinv;
   114         expected_visibles = vis;
   115         expected_invisibles = inv;
   116         File testFile = null;
   117         String tname="Test" + N.toString();
   118         hasInnerClass=false;
   119         String testDef = "Test " + testcount + " parameters: tinv=" + tinv +
   120                 ", tvis=" + tvis + ", inv=" + inv + ", vis=" + vis +
   121                 ", Arepeats=" + Arepeats + ", BDrepeats=" + BDrepeats +
   122                 ", ABmix=" + ABmix + ", retention: " + rtn + ", anno2: " +
   123                 et2 + ", src=" + source;
   125         println(testDef);
   126         // Create test source and File.
   127         String sourceString = sourceString(tname, rtn, et2, Arepeats,
   128                                            BDrepeats, ABmix, source);
   129         testFile = writeTestFile(tname+".java", sourceString);
   130         // Compile test source and read classfile.
   131         File classFile = null;
   132         try {
   133             classFile = compile(testFile);
   134         } catch (Error err) {
   135             System.err.println("Failed compile. Source:\n" + sourceString);
   136             throw err;
   137         }
   138         //if sourcString() set hasInnerClass it also set innerClassname.
   139         if(hasInnerClass) {
   140             StringBuffer sb = new StringBuffer(classFile.getAbsolutePath());
   141             classFile=new File(sb.insert(sb.lastIndexOf(".class"),
   142                                          innerClassname).toString());
   143         }
   144         ClassFile cf = ClassFile.read(classFile);
   146         //Test class,fields and method counts.
   147         test(cf);
   149         for (Field f : cf.fields) {
   150             test(cf, f);
   151         }
   152         for (Method m: cf.methods) {
   153             test(cf, m);
   154         }
   155         countAnnotations();
   156         if (errors > 0) {
   157             System.err.println( testDef );
   158             System.err.println( "Source:\n" + sourceString );
   159             throw new Exception( errors + " errors found" );
   160         }
   161         println("Pass");
   162     }
   164     //
   165     // Source for test cases
   166     //
   167     String sourceString(String testname, String retentn, String annot2,
   168                         Boolean Arepeats, Boolean BDrepeats, Boolean ABmix,
   169                         srce src) {
   171         String As = "@A", Bs = "@B", Ds = "@D";
   172         if(Arepeats) As = "@A @A";
   173         if(BDrepeats) {
   174             Bs = "@B @B";
   175             Ds = "@D @D";
   176         }
   177         if(ABmix) { As = "@A @B"; Bs = "@A @B"; Ds = "@D @D"; }
   179         // Source to check for TYPE_USE and TYPE_PARAMETER annotations.
   180         // Source base (annotations) is same for all test cases.
   181         String source = new String();
   182         String imports = new String("import java.lang.annotation.*; \n" +
   183             "import static java.lang.annotation.RetentionPolicy.*; \n" +
   184             "import static java.lang.annotation.ElementType.*; \n" +
   185             "import java.util.List; \n" +
   186             "import java.util.HashMap; \n" +
   187             "import java.util.Map; \n\n");
   189             String sourceBase = new String("@Retention("+retentn+")\n" +
   190             "@Target({TYPE_USE,_OTHER_})\n" +
   191             "@Repeatable( AC.class )\n" +
   192             "@interface A { }\n\n" +
   194             "@Retention("+retentn+")\n" +
   195             "@Target({TYPE_USE,_OTHER_})\n" +
   196             "@interface AC { A[] value(); }\n\n" +
   198             "@Retention("+retentn+")\n" +
   199             "@Target({TYPE_USE,_OTHER_})\n" +
   200             "@Repeatable( BC.class )\n" +
   201             "@interface B { }\n\n" +
   203             "@Retention("+retentn+")\n" +
   204             "@Target({TYPE_USE,_OTHER_})\n" +
   205             "@interface BC { B[] value(); } \n\n" +
   207             "@Retention("+retentn+")\n" +
   208             "@Target({TYPE_PARAMETER,_OTHER_})\n" +
   209             "@interface C { }\n\n" +
   211             "@Retention("+retentn+")\n" +
   212             "@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" +
   213             "@Repeatable(DC.class)\n" +
   214             "@interface D { }\n\n" +
   216             "@Retention("+retentn+")\n" +
   217             "@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" +
   218             "@interface DC { D[] value(); }\n");
   220         // Test case sources with sample generated source.
   221         switch(src) {
   222             case src1: // repeating type annotations at class level
   223                     /*
   224                      * @A @B class Test1 {
   225                      * @A @B Test1(){}
   226                      * @A @B Integer i1 = 0;
   227                      * String @A @B [] @A @B [] sa = null;
   228                      * // type usage in method body
   229                      * String test(Test1 this, String param, String ... vararg) {
   230                      *     Object o = new  String  [3];
   231                      *     return (String) null;
   232                      * }}
   233                      */
   234                 source = new String(
   235                     "// " + src.description + "\n" +
   236                     "_As_ _Bs_ class " + testname + " {\n" +
   237                     "_As_ _Bs_ " + testname +"(){} \n" +
   238                     "_As_ _Bs_ Integer i1 = 0; \n" +
   239                     "String _As_ _Bs_ [] _As_ _Bs_ [] sa = null; \n" +
   240                     "// type usage in method body \n" +
   241                     "String test("+testname+" this, " +
   242                        "String param, String ... vararg) { \n" +
   243                     "    Object o = new  String  [3]; \n" +
   244                     "    return (String) null; \n" +
   245                     "}\n" +
   246                     "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
   247                     "\n";
   248                 break;
   249             case src2: // (repeating) type annotations on method.
   250                     /*
   251                      * class Test12 {
   252                      * Test12(){}
   253                      * // type usage on method
   254                      * @A @B String test(@A @B  Test12 this, @A @B  String param, @A @B  String @A @B  ... vararg) {
   255                      *     Object o = new String [3];
   256                      *     return (String) null;
   257                      * }}
   258                      */
   259                 source = new String(
   260                     "// " + src.description + "\n" +
   261                     "class " + testname + " {\n" +
   262                     testname +"(){} \n" +
   263                     "// type usage on method \n" +
   264                     "_As_ _Bs_ String test(_As_ _Bs_  "+testname+" this, " +
   265                        "_As_ _Bs_  String param, _As_ _Bs_  String _As_ _Bs_  ... vararg) { \n" +
   266                     "    Object o = new String [3]; \n" +
   267                     "    return (String) null; \n" +
   268                     "}\n" +
   269                     "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
   270                     "\n";
   271                 break;
   272             case src3: //(repeating) annotations on wildcard, type arguments in anonymous class.
   273                     /*
   274                      * class Test13<T extends Object> {
   275                      *     public T data = null;
   276                      *     T getData() { return data;}
   277                      *     String mtest( Test13<String> t){ return t.getData(); }
   278                      *     public void test() {
   279                      *         mtest( new Test13<String>() {
   280                      *                  void m1(List<@A @B ? extends @A @B  Object> lst) {}
   281                      *                  void m2() throws@A @B Exception { }
   282                      *                });
   283                      *     }
   284                      * }
   285                      */
   286                 source = new String( source +
   287                     "// " + src.description + "\n" +
   288                     "class " + testname + "<T extends Object> {\n" +
   289                     "    public T data = null;\n" +
   290                     "    T getData() { return data;}\n" +
   291                     "    String mtest( " + testname + "<String> t){ return t.getData(); }\n" +
   292                     "    public void test() {\n" +
   293                     "        mtest( new " + testname + "<String>() {\n" +
   294                     "                 void m1(List<_As_ _Bs_ ? extends _As_ _Bs_  Object> lst) {}\n" +
   295                     "                 void m2() throws_As_ _Bs_ Exception { }\n" +
   296                     "               });\n" +
   297                     "    }\n" +
   298                     "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
   299                     "\n";
   300                     hasInnerClass=true;
   301                     innerClassname="$1";
   302             break;
   303             case src4: // (repeating)annotations on type parameters, bounds and  type arguments on class decl.
   304                     /*
   305                      * @A @B @D
   306                      * class Test2<@A @B @C @D T extends @A @B Object> {
   307                      *     Map<List<String>, Integer> map =
   308                      *         new HashMap<List< String>, Integer>();
   309                      *     Map<List<String>,Integer> map2 = new HashMap<>();
   310                      *     String test(Test2<T> this) { return null;}
   311                      *     <T> String genericMethod(T t) { return null; }
   312                      * }
   313                      */
   314                 source = new String( source +
   315                     "// " + src.description + "\n" +
   316                     "_As_ _Bs_ _Ds_\n" +  //8004829: A and B on type parameter below.
   317                     "class " + testname + "<_As_ _Bs_ @C _Ds_ T extends _As_ _Bs_ Object> {\n" +
   318                     "    Map<List<String>, Integer> map =\n" +
   319                     "        new HashMap<List< String>, Integer>();\n" +
   320                     "    Map<List<String>,Integer> map2 = new HashMap<>();\n" +
   321                     "    String test(" + testname + "<T> this) { return null;}\n" +
   322                     "    <T> String genericMethod(T t) { return null; }\n" +
   323                     "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
   324                     "\n";
   325                 break;
   326             case src5: // (repeating) annotations on type parameters, bounds and  type arguments on method.
   327                     /*
   328                      * class Test14<T extends Object> {
   329                      *     Map<List<String>, Integer> map =
   330                      *         new HashMap<List<String>, Integer>();
   331                      *     Map<List<String>, Integer> map2 = new HashMap<>();
   332                      *     String test(@A @B Test14<@D T> this) { return null;}
   333                      *     <@C @D T> @A @B String genericMethod(@A @B @D T t) { return null; }
   334                      * }
   335                      */
   336                 source = new String( source +
   337                     "// " + src.description + "\n" +
   338                     "class " + testname + "<T extends Object> {\n" +
   339                     "    Map<List<String>, Integer> map =\n" +
   340                     "        new HashMap<List<String>, Integer>();\n" +
   341                     "    Map<List<String>, Integer> map2 = new HashMap<>();\n" +
   342                     "    String test(_As_ _Bs_ " + testname + "<_Ds_ T> this) { return null;}\n" +
   343                     "    <@C _Ds_ T> _As_ _Bs_ String genericMethod(_As_ _Bs_ _Ds_ T t) { return null; }\n" +
   344                     "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
   345                     "\n";
   346                 break;
   347             case src6: // repeating annotations on type parameters, bounds and  type arguments in method.
   348                     /*
   349                      * class Test7{
   350                      *     <E extends Comparable> Map<List<E>, E > foo(E e) {
   351                      *         class maptest <@A @B @D E> {
   352                      *             Map<List<@A @B @D E>,@A @B @D E> getMap() {
   353                      *                 return new HashMap<List<E>,E>();
   354                      *             }
   355                      *         }
   356                      *         return new maptest<E>().getMap();
   357                      *    }
   358                      *    Map<List<String>,String> shm = foo(new String("hello"));
   359                      * }
   360                      */
   361                 source = new String( source +
   362                     "// " + src.description + "\n" +
   363                     "class "+ testname + "{\n" +
   364                     "    <E extends Comparable> Map<List<E>, E > foo(E e) {\n" +
   365                     "        class maptest <_As_ _Bs_ _Ds_ E> {\n" +                  // inner class $1maptest
   366                     "            Map<List<_As_ _Bs_ _Ds_ E>,_As_ _Bs_ _Ds_ E> getMap() { \n" +
   367                     "                return new HashMap<List<E>,E>();\n" +
   368                     "            }\n" +
   369                     "        }\n" +
   370                     "        return new maptest<E>().getMap();\n" +
   371                     "   }\n" +
   372                     "   Map<List<String>,String> shm = foo(new String(\"hello\"));\n" +
   373                     "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
   374                     "\n";
   375                     hasInnerClass=true;
   376                     innerClassname="$1maptest";
   377                 break;
   378         }
   379         return imports + source;
   380     }
   381 }

mercurial