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