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 8008762 8008751 8013065
  27  * @summary Type annotations on anonymous and inner class.
  28  *  Six TYPE_USE annotations are repeated(or not); Four combinations create
  29  *  four test files, and each results in the test class and 2 anonymous classes.
  30  *  Each element of these three classes is checked for expected number of the 
  31  *  four annotation Attributes. Expected annotation counts depend on type of 
  32  *  annotation place on type of element (a FIELD&TYPE_USE element on a field 
  33  *  results in 2). Elements with no annotations expect 0.
  34  *
  35  */
  36 import java.lang.annotation.*;
  37 import java.io.*;
  38 import java.util.List;
  39 import com.sun.tools.classfile.*;
  40 
  41 import java.lang.annotation.*;
  42 import static java.lang.annotation.RetentionPolicy.*;
  43 import static java.lang.annotation.ElementType.*;
  44 
  45 public class TestAnonInnerClasses extends ClassfileTestHelper {
  46     // tally errors and test cases
  47     int errors = 0;
  48     int checks = 0;
  49 
  50     String[] AnnoAttributes = {
  51         Attribute.RuntimeVisibleTypeAnnotations,
  52         Attribute.RuntimeInvisibleTypeAnnotations,
  53         Attribute.RuntimeVisibleAnnotations,
  54         Attribute.RuntimeInvisibleAnnotations
  55     };
  56 
  57     // Four test files generated based on combinations of repeating annotations.
  58     Boolean As= false, Bs=true, Cs=false, Ds=false, TAs=false,TBs=false;
  59     Boolean [][] bRepeat = new Boolean[][]{
  60                  /* no repeats    */ {false, false, false, false, false, false}
  61                  /* repeat A,C,TA */ //{true,  false, true,  false, true,  false}
  62                  /* repeat B,D,TB  {false, true,  false, true,  false, true}, */
  63                  /* repeat all     {true,  true,  true,  true,  true,  true}*/
  64     };
  65     // Save descriptions of failed test case; does not terminate upon a failure.
  66     List<String> failed = new java.util.LinkedList<>();
  67 
  68     public static void main(String[] args) throws Exception {
  69         new TestAnonInnerClasses().run();
  70     }
  71 
  72     // Check annotation counts and make reports sufficiently descriptive to 
  73     // easily diagnose.
  74     void check(String testcase, int vtaX, int itaX, int vaX, int iaX, 
  75                                 int vtaA, int itaA, int vaA, int iaA) {
  76 
  77         String descr = " checking " + testcase+" _TYPE_, expected: " + 
  78             vtaX + ", " + itaX + ", " + vaX + ", " + iaX + "; actual: " + 
  79             vtaA + ", " + itaA + ", " + vaA + ", " + iaA;
  80         String description;
  81         description=descr.replace("_TYPE_","RuntimeVisibleTypeAnnotations");
  82         if(vtaX != vtaA) {
  83             errors++;
  84             failed.add(++checks + " " + testcase + ": (vtaX) " + vtaX + " != " + vtaA + " (vtaA)");
  85             println(checks + " FAIL: " + description);
  86         } else println(++checks + " PASS: " + description);
  87         description=descr.replace("_TYPE_","RuntimeInvisibleTypeAnnotations");
  88         if(itaX != itaA) {
  89             errors++;
  90             failed.add(++checks + " " + testcase + ": (itaX) " + itaX + " != " + itaA + " (itaA)");
  91             println(checks + " FAIL: " + description);
  92         } else println(++checks + " PASS: " + description);
  93         description=descr.replace("_TYPE_","RuntimeVisibleAnnotations");
  94         if(vaX != vaA) {
  95             errors++;
  96             failed.add(++checks + " " + testcase + ": (vaX) " + vaX + " != " + vaA + " (vaA)");
  97             println(checks + " FAIL: " + description);
  98         } else println(++checks + " PASS: " + description);
  99         description=descr.replace("_TYPE_","RuntimeInvisibleAnnotations");
 100         if(iaX != iaA) {
 101             errors++;
 102             failed.add(++checks + " " + testcase + ": (iaX) " + iaX + " != " + iaA + " (iaA)");
 103             println(checks + " FAIL: " + description);
 104         } else println(++checks + " PASS: " + description);
 105         println("");
 106     }
 107 
 108     // Print failed cases (if any) and throw exception for fail.
 109     void report() {
 110         if(errors!=0) {
 111             System.err.println("Failed tests: " + errors +
 112                                "\nfailed test cases:\n");
 113             for(String t: failed) System.err.println("  " + t);
 114             throw new RuntimeException("FAIL: There were test failures.");
 115         } else
 116             System.out.println("PASSED all tests.");
 117     }
 118 
 119     void test(String ttype, ClassFile cf, Method m, Field f, boolean visible) {
 120         int vtaActual = 0, itaActual = 0, vaActual = 0, iaActual = 0,
 121             vtaExp = 0,    itaExp = 0,    vaExp = 0,    iaExp = 0, 
 122             index = 0, index2 = 0;
 123         String memberName = null, testcase = "undefined", testClassName = null;
 124         Attribute attr = null, cattr = null;
 125         Code_attribute CAttr = null;
 126         // Get counts of 4 annotation Attributes on element being checked.
 127         for (String AnnoType : AnnoAttributes) {
 128             try {
 129                 switch(ttype) {
 130                     case "METHOD":
 131                         index = m.attributes.getIndex(cf.constant_pool,
 132                                                       AnnoType);
 133                         memberName = m.getName(cf.constant_pool);
 134                         if(index != -1) 
 135                             attr = m.attributes.get(index);
 136                         //fetch index annotations from code attribute.
 137                         index2 = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
 138                         if(index2 != -1) {
 139                             cattr = m.attributes.get(index2);
 140                             assert cattr instanceof Code_attribute;
 141                             CAttr = (Code_attribute)cattr;
 142                             index2 = CAttr.attributes.getIndex(cf.constant_pool, AnnoType); 
 143                             if(index2 != -1) 
 144                                 cattr = CAttr.attributes.get(index2);
 145                         }
 146                         break;
 147                     case "FIELD":
 148                         index = f.attributes.getIndex(cf.constant_pool,
 149                                                       AnnoType);
 150                         memberName = f.getName(cf.constant_pool);
 151                         if(index != -1) 
 152                             attr = f.attributes.get(index);
 153                         //fetch index annotations from code attribute.
 154                         index2 = cf.attributes.getIndex(cf.constant_pool, Attribute.Code);
 155                         if(index2!= -1) {
 156                             cattr = cf.attributes.get(index2);
 157                             assert cattr instanceof Code_attribute;
 158                             CAttr = (Code_attribute)cattr;
 159                             index2 = CAttr.attributes.getIndex(cf.constant_pool, AnnoType); 
 160                             if(index2!= -1) 
 161                                 cattr = CAttr.attributes.get(index2);
 162                         }
 163                         break;
 164 
 165                     default:
 166                         memberName = cf.getName();
 167                         index = cf.attributes.getIndex(cf.constant_pool, AnnoType);
 168                         if(index!= -1) attr = cf.attributes.get(index);
 169                         break;
 170                 }
 171             } catch(ConstantPoolException cpe) { cpe.printStackTrace(); }
 172             try {
 173                 testClassName=cf.getName();
 174                 testcase = ttype + ": " + testClassName + ": " +
 175                            memberName + ", ";
 176             } catch(ConstantPoolException cpe) { cpe.printStackTrace(); }
 177             if(index != -1) {
 178                 switch(AnnoType) {
 179                     case Attribute.RuntimeVisibleTypeAnnotations:
 180                         //count RuntimeVisibleTypeAnnotations
 181                         RuntimeVisibleTypeAnnotations_attribute RVTAa =
 182                                 (RuntimeVisibleTypeAnnotations_attribute)attr;
 183                         vtaActual += RVTAa.annotations.length;
 184                         break;
 185                     case Attribute.RuntimeVisibleAnnotations:
 186                         //count RuntimeVisibleAnnotations
 187                         RuntimeVisibleAnnotations_attribute RVAa =
 188                                 (RuntimeVisibleAnnotations_attribute)attr;
 189                         vaActual += RVAa.annotations.length;
 190                         break;
 191                     case Attribute.RuntimeInvisibleTypeAnnotations:
 192                         //count RuntimeInvisibleTypeAnnotations
 193                         RuntimeInvisibleTypeAnnotations_attribute RITAa =
 194                                 (RuntimeInvisibleTypeAnnotations_attribute)attr;
 195                         itaActual += RITAa.annotations.length;
 196                         break;
 197                     case Attribute.RuntimeInvisibleAnnotations:
 198                         //count RuntimeInvisibleAnnotations
 199                         RuntimeInvisibleAnnotations_attribute RIAa =
 200                                 (RuntimeInvisibleAnnotations_attribute)attr;
 201                         iaActual += RIAa.annotations.length;
 202                         break;
 203                 }
 204             }
 205     //////////////////////////////////////////////////////////////////
 206             if(index2 != -1) {
 207                 switch(AnnoType) {
 208                     case Attribute.RuntimeVisibleTypeAnnotations:
 209                         //count RuntimeVisibleTypeAnnotations
 210                         RuntimeVisibleTypeAnnotations_attribute RVTAa =
 211                                 (RuntimeVisibleTypeAnnotations_attribute)cattr;
 212                         vtaActual += RVTAa.annotations.length;
 213                         break;
 214                     case Attribute.RuntimeVisibleAnnotations:
 215                         //count RuntimeVisibleAnnotations
 216                         RuntimeVisibleAnnotations_attribute RVAa =
 217                                 (RuntimeVisibleAnnotations_attribute)cattr;
 218                         vaActual += RVAa.annotations.length;
 219                         break;
 220                     case Attribute.RuntimeInvisibleTypeAnnotations:
 221                         //count RuntimeInvisibleTypeAnnotations
 222                         RuntimeInvisibleTypeAnnotations_attribute RITAa =
 223                                 (RuntimeInvisibleTypeAnnotations_attribute)cattr;
 224                         itaActual += RITAa.annotations.length;
 225                         break;
 226                     case Attribute.RuntimeInvisibleAnnotations:
 227                         //count RuntimeInvisibleAnnotations
 228                         RuntimeInvisibleAnnotations_attribute RIAa =
 229                                 (RuntimeInvisibleAnnotations_attribute)cattr;
 230                         iaActual += RIAa.annotations.length;
 231                         break;
 232                 }
 233             }
 234     //////////////////////////////////////////////////////////////////
 235         }
 236 
 237         switch ( memberName ) {
 238             //METHODs 
 239             case "test" :
 240                 vtaExp=4;  itaExp=4;  vaExp=0; iaExp=0;//from IN
 241                 if(testClassName.compareTo("Test4")==0) {
 242                     println("8008769: workaround " + testClassName + ":test");
 243                     vtaExp=2;  itaExp=2;  vaExp=0; iaExp=0;
 244                 }
 245                 break;              
 246             case "mtest": vtaExp=4;  itaExp=4;  vaExp=1; iaExp=1; break;
 247             case "m1":    vtaExp=2;  itaExp=2;  vaExp=1; iaExp=1; break;
 248             case "m2":    vtaExp=4;  itaExp=4;  vaExp=1; iaExp=1; break;
 249             case "m3":    vtaExp=10; itaExp=10; vaExp=1; iaExp=1; break;
 250             case "tm":    vtaExp=6;  itaExp=6;  vaExp=1; iaExp=1; break;
 251             //inner class
 252             case "i_m1":  vtaExp=2;  itaExp=2; vaExp=1; iaExp=1; break;
 253             case "i_m2":  vtaExp=4;  itaExp=4; vaExp=1; iaExp=1; break;
 254             case "i_um":  vtaExp=6;  itaExp=6; vaExp=1; iaExp=1; break;
 255             //local class
 256             case "l_m1":  vtaExp=2;  itaExp=2; vaExp=1; iaExp=1; break;
 257             case "l_m2":  vtaExp=4;  itaExp=4; vaExp=1; iaExp=1; break;
 258             case "l_um":  vtaExp=6;  itaExp=6; vaExp=1; iaExp=1; break;
 259             //anon class
 260             case "mm_m1": vtaExp=2;  itaExp=2; vaExp=1; iaExp=1; break;
 261             case "mm_m2": vtaExp=4;  itaExp=4; vaExp=1; iaExp=1; break;
 262             case "mm_m3": vtaExp=10; itaExp=10; vaExp=1; iaExp=1; break;
 263             case "mm_tm": vtaExp=6;  itaExp=6; vaExp=1; iaExp=1; break;
 264             //InnerAnon class
 265             case "ia_m1":  vtaExp=2;  itaExp=2; vaExp=1; iaExp=1; break;
 266             case "ia_m2":  vtaExp=4;  itaExp=4; vaExp=1; iaExp=1; break;
 267             case "ia_um":  vtaExp=6;  itaExp=6; vaExp=1; iaExp=1; break;
 268             //FIELDs
 269             case "data":      vtaExp = 2;  itaExp=2; vaExp=1; iaExp=1; break;
 270             case "odata1":    vtaExp = 2;  itaExp=2; vaExp=1; iaExp=1; break;
 271             case "pdata1":    vtaExp = 2;  itaExp=2; vaExp=1; iaExp=1; break;
 272             case "tdata":     vtaExp = 2;  itaExp=2; vaExp=1; iaExp=1; break;
 273             case "sa1":       vtaExp = 6;  itaExp=6; vaExp=1; iaExp=1; break;
 274             //inner class
 275             case "i_odata1":  vtaExp=2;  itaExp=2; vaExp=1; iaExp=1; break;
 276             case "i_pdata1":  vtaExp=2;  itaExp=2; vaExp=1; iaExp=1; break;
 277             case "i_udata":   vtaExp=2;  itaExp=2; vaExp=1; iaExp=1; break;
 278             case "i_sa1":     vtaExp=6;  itaExp=6; vaExp=1; iaExp=1; break;
 279             case "i_tdata":   vtaExp=2;  itaExp=2; vaExp=1; iaExp=1; break;
 280             //local class
 281             case "l_odata1":  vtaExp=2;  itaExp=2; vaExp=1; iaExp=1; break;
 282             case "l_pdata1":  vtaExp=2;  itaExp=2; vaExp=1; iaExp=1; break;
 283             case "l_udata":   vtaExp=2;  itaExp=2; vaExp=1; iaExp=1; break;
 284             case "l_sa1":     vtaExp=6;  itaExp=6; vaExp=1; iaExp=1; break;
 285             case "l_tdata":   vtaExp=2;  itaExp=2; vaExp=1; iaExp=1; break;
 286             //anon class
 287             case "mm_odata1": vtaExp = 2;  itaExp=2; vaExp=1; iaExp=1; break;
 288             case "mm_pdata1": vtaExp = 2;  itaExp=2; vaExp=1; iaExp=1; break;
 289             case "mm_sa1":    vtaExp = 6;  itaExp=6; vaExp=1; iaExp=1; break;
 290             case "mm_tdata":  vtaExp = 2;  itaExp=2; vaExp=1; iaExp=1; break;
 291             // InnerAnon class
 292             case "ia_odata1": vtaExp=2;  itaExp=2; vaExp=1; iaExp=1; break;
 293             case "ia_pdata1": vtaExp=2;  itaExp=2; vaExp=1; iaExp=1; break;
 294             case "ia_udata":  vtaExp=2;  itaExp=2; vaExp=1; iaExp=1; break;
 295             case "ia_sa1":  vtaExp=6;  itaExp=6; vaExp=1; iaExp=1; break;
 296             case "ia_tdata":  vtaExp=2;  itaExp=2; vaExp=1; iaExp=1; break;
 297             case "IA":        vtaExp=4;  itaExp=4; vaExp=1; iaExp=1; break; 
 298             case "IN":        vtaExp=4;  itaExp=4; vaExp=1; iaExp=1; break; 
 299 
 300             default:          vtaExp = 0;  itaExp=0; vaExp=0; iaExp=0; break;
 301         }
 302         check(testcase,vtaExp,   itaExp,   vaExp,   iaExp,
 303                        vtaActual,itaActual,vaActual,iaActual);
 304     }
 305 
 306     public void run() {
 307         ClassFile cf   = null;
 308         InputStream in = null;
 309         int testcount  = 1;
 310         File testFile  = null;
 311         // Generate source, check methods and fields for each combination.
 312         for(Boolean[] bCombo : bRepeat) {
 313             As=bCombo[0]; Bs=bCombo[1]; Cs=bCombo[2];
 314             Ds=bCombo[3]; TAs=bCombo[4]; TBs=bCombo[5];
 315             String testname = "Test" + testcount++;
 316             println("Combinations: " + As + ", " + Bs + ", " + Cs + ", " + Ds +  
 317                                 ", " + TAs + ", " + TBs + 
 318                                 "; see " + testname + ".java");
 319             String[] classes = {testname + ".class", 
 320                                 testname + "$Inner.class", 
 321                                 testname + "$1Local1.class",
 322                                 testname + "$1.class", 
 323                                 testname + "$1$1.class", 
 324                                 testname + "$1$InnerAnon.class"
 325             };
 326             // Create test source and File.
 327             String sourceString = getSource(testname, As, Bs, Cs, Ds, TAs, TBs);
 328             //(sourceString);
 329             try {
 330              testFile = writeTestFile(testname+".java", sourceString);
 331             } catch( java.io.IOException ioe) { ioe.printStackTrace(); }
 332             // Compile test source and read classfile.
 333             File classFile = null; 
 334             try {
 335                 classFile = compile(testFile);
 336             } catch (Error err) {
 337                 System.err.println("FAILED compile. Source:\n" + sourceString);
 338                 throw err;
 339             }
 340             String testloc = classFile.getAbsolutePath().substring( 
 341                    0,classFile.getAbsolutePath().indexOf(classFile.getPath()));
 342             for(String clazz : classes) {
 343                 try {
 344                     cf = ClassFile.read(new File(testloc+clazz));
 345                 } catch(Exception e) { e.printStackTrace();  }
 346                 // Test for all methods and fields
 347                 for (Method m: cf.methods) {
 348                     test("METHOD", cf, m, null, true);
 349                 }
 350                 for (Field f: cf.fields) {
 351                     test("FIELD", cf, null, f, true);
 352                 }
 353             }
 354         }
 355         report();
 356     }
 357 
 358     // test class template
 359     String getSource(String testname, Boolean Arepeats,  Boolean Brepeats, 
 360                                       Boolean Crepeats,  Boolean Drepeats, 
 361                                       Boolean TArepeats, Boolean TBrepeats ) {
 362         String As  = Arepeats  ? "@A @A":"@A",
 363                Bs  = Brepeats  ? "@B @B":"@B",
 364                Cs  = Crepeats  ? "@C @C":"@C",
 365                Ds  = Drepeats  ? "@D @D":"@D",
 366                TAs = TArepeats ? "@TA @TA":"@TA",
 367                TBs = TBrepeats ? "@TB @TB":"@TB";
 368 
 369         String imports = new String("import java.lang.annotation.*; \n" +
 370             "import static java.lang.annotation.RetentionPolicy.*; \n" +
 371             "import static java.lang.annotation.ElementType.*; \n" +
 372             "import java.util.List; \n\n");
 373 
 374         String testsource = 
 375         "class " + testname + "<T> {                 // TestN.class\n" +
 376         "    _As _Bs _Cs _Ds String data = \"test\";\n" +
 377         "    _As _Bs _Cs _Ds Object mtest( _As _Bs _Cs _Ds " + testname + "<T> t){ return null;  }\n" +
 378         "    Object mmtest( " + testname + "<T> t){ return null;  }\n" +
 379         "\n" +
 380         "    class Inner<U> {        // TestN$1$InnerAnon.class\n" +
 381         "         _As _Bs _Cs _Ds String i_odata1 = \"test\";\n" +
 382         "         _As _Bs _Cs _Ds int    i_pdata1 = 0;\n" +
 383         "         _As _Bs _Cs _Ds U      i_udata = null;\n" +
 384         "         _As _Bs _Cs _Ds Object  _As _Bs _Cs _Ds [] _As _Bs _Cs _Ds [] i_sa1 = null;\n" +
 385         "         _As _Bs _Cs _Ds  T    i_tdata = null;\n" +
 386         "         _As _Bs _Cs _Ds String i_m1(){ return null; };\n" +
 387         "         _As _Bs _Cs _Ds int    i_m2( _As _Bs _Cs _Ds Object o){return 0;}\n" +
 388         "         _As _Bs _Cs _Ds\n" +
 389         "        <_TAs _TBs _Cs _Ds U> Object i_um( _As _Bs _Cs _Ds  U u) { return null; }\n" +
 390         "    }\n" +
 391         "     _As _Bs _Cs _Ds Inner< _As _Bs _Cs _Ds String> IN = new  Inner< String>();\n" +
 392         "\n" +
 393         "    public void test() {\n" +
 394         " \n" +
 395         "        class Local1<U> {                   // TestN$Local1.class\n" +
 396         "            _As _Bs _Cs _Ds  String l_odata1 = \"test\";\n" +
 397         "            _As _Bs _Cs _Ds  int    l_pdata1 = 0;\n" +
 398         "            _As _Bs _Cs _Ds  U      l_udata = null;\n" +
 399         "            _As _Bs _Cs _Ds  Object _As _Bs _Cs _Ds  []_As _Bs _Cs _Ds  [] l_sa1 = null;\n" +
 400         "            _TAs _TBs _Cs _Ds  T    l_tdata = null;\n" +
 401         "            _As _Bs _Cs _Ds  String l_m1(){ return null; };\n" +
 402         "            _As _Bs _Cs _Ds  int    l_m2(_As _Bs _Cs _Ds  Object o){return 0;}\n" +
 403         "            _As _Bs _Cs _Ds \n" +
 404         "            <_TAs _TBs _Cs _Ds  U> Object l_um(_As _Bs _Cs _Ds   U u) { return null; }\n" +
 405         "        }\n" +
 406         "        // The below, as a local variable, will show up on test()\n" +
 407         "       _As _Bs _Cs _Ds  Local1<_As _Bs _Cs _Ds  String> LC = new Local1<String>();\n" +
 408         " \n" +
 409         "        mtest( new " + testname + "<T>() {  // TestN$1\n" +
 410         "                class InnerAnon<U> {        // TestN$1$InnerAnon.class\n" +
 411         "                    _As _Bs _Cs _Ds  String ia_odata1 = \"test\";\n" +
 412         "                    _As _Bs _Cs _Ds  int    ia_pdata1 = 0;\n" +
 413         "                    _As _Bs _Cs _Ds  U      ia_udata = null;\n" +
 414         "                    _As _Bs _Cs _Ds  Object _As _Bs _Cs _Ds  []_As _Bs _Cs _Ds  [] ia_sa1 = null;\n" +
 415         "                    _TAs _TBs _Cs _Ds  T    ia_tdata = null;\n" +
 416         "                    _As _Bs _Cs _Ds  String ia_m1(){ return null; };\n" +
 417         "                    _As _Bs _Cs _Ds  int    ia_m2(_As _Bs _Cs _Ds  Object o){return 0;}\n" +
 418         "                    _As _Bs _Cs _Ds \n" +
 419         "                    <_TAs _TBs _Cs _Ds  U> Object ia_um(_As _Bs _Cs _Ds   U u) { return null; }\n" +
 420         "                }\n" +
 421         "                _As _Bs _Cs _Ds  InnerAnon<_As _Bs _Cs _Ds  String> IA = new InnerAnon< String>();\n" +
 422         "\n" +
 423         "                _As _Bs _Cs _Ds String odata1 = \"test\";\n" +
 424         "                _As _Bs _Cs _Ds int    pdata1 = 0;\n" +
 425         "                _As _Bs _Cs _Ds Object _As _Bs _Cs _Ds []_As _Bs _Cs _Ds [] sa1 = null;\n" +
 426         "                _As _Bs _Cs _Ds T tdata = null;\n" +
 427         "\n" +
 428         "                _As _Bs _Cs _Ds String m1(){ return null; };\n" +
 429         "                _As _Bs _Cs _Ds int    m2(_As _Bs _Cs _Ds Object o){return 0;}\n" +
 430         "\n" +
 431         "                _As _Bs _Cs _Ds Object _As _Bs _Cs _Ds [] _As _Bs _Cs _Ds []\n" +
 432         "                m3(String _As _Bs _Cs _Ds []_As _Bs _Cs _Ds [] sa){ return null; }\n" +
 433         "\n" +
 434         "                _As _Bs _Cs _Ds\n" +
 435         "                <_TAs _TBs _Cs _Ds T> Object tm(_As _Bs _Cs _Ds  T t) { return null; }\n" +
 436         "\n" +
 437         "                public void atest( " + testname + "<T> t){\n" +
 438         "                    t.mmtest( new " + testname + "<T>() {   // TestN$1$1.class \n" +
 439         "                        _As _Bs _Cs _Ds String mm_odata1 = \"test\";\n" +
 440         "                        _As _Bs _Cs _Ds int    mm_pdata1 = 0;\n" +
 441         "                        _As _Bs _Cs _Ds Object _As _Bs _Cs _Ds []_As _Bs _Cs _Ds [] mm_sa1 = null;\n" +
 442         "                        _TAs _TBs _Cs _Ds T mm_tdata = null;\n" +
 443         "\n" +
 444         "                        _As _Bs _Cs _Ds String mm_m1(){ return null; };\n" +
 445         "                        _As _Bs _Cs _Ds int    mm_m2(_As _Bs _Cs _Ds Object o){return 0;}\n" +
 446         "\n" +
 447         "                        _As _Bs _Cs _Ds String _As _Bs _Cs _Ds [] _As _Bs _Cs _Ds []\n" +
 448         "                        mm_m3(String _As _Bs _Cs _Ds []_As _Bs _Cs _Ds [] sa){ return null; }\n" +
 449         "\n" +
 450         "                        _As _Bs _Cs _Ds\n" +
 451         "                        <_TAs _TBs _Cs _Ds T> Object mm_tm(_As _Bs _Cs _Ds  T t) { return null; }\n" +
 452         "                    });\n" +
 453         "                }\n" +
 454         "           });\n" +
 455         "   }\n" +
 456         "}\n\n" +
 457         "@Retention(RUNTIME) @Target({TYPE_USE,FIELD})  @Repeatable( AC.class ) @interface A { }\n" +
 458         "@Retention(RUNTIME) @Target({TYPE_USE,METHOD}) @Repeatable( BC.class ) @interface B { }\n" +
 459         "@Retention(RUNTIME) @Target({TYPE_USE,FIELD})  @interface AC { A[] value(); }\n" +
 460         "@Retention(RUNTIME) @Target({TYPE_USE,METHOD}) @interface BC { B[] value(); }\n" +
 461         "\n" +
 462         "@Retention(CLASS)   @Target({TYPE_USE,FIELD})  @Repeatable( CC.class ) @interface C { }\n" +
 463         "@Retention(CLASS)   @Target({TYPE_USE,METHOD}) @Repeatable( DC.class ) @interface D { }\n" +
 464         "@Retention(CLASS)   @Target({TYPE_USE,FIELD})  @interface CC { C[] value(); }\n" +
 465         "@Retention(CLASS)   @Target({TYPE_USE,METHOD}) @interface DC { D[] value(); }\n" +
 466         "\n" +
 467         "@Retention(RUNTIME) @Target({TYPE_USE,TYPE_PARAMETER,FIELD})  @Repeatable( TAC.class ) @interface TA { }\n" +
 468         "@Retention(RUNTIME) @Target({TYPE_USE,TYPE_PARAMETER,METHOD}) @Repeatable( TBC.class ) @interface TB { }\n" +
 469         "@Retention(RUNTIME) @Target({TYPE_USE,TYPE_PARAMETER,FIELD})  @interface TAC { TA[] value(); }\n" +
 470         "@Retention(RUNTIME) @Target({TYPE_USE,TYPE_PARAMETER,METHOD}) @interface TBC { TB[] value(); }\n";
 471 
 472         return imports.concat(testsource).replace("_As",As).replace("_Bs",Bs).replace("_Cs",Cs).replace("_Ds",Ds).replace("_TAs",TAs).replace("_TBs",TBs);
 473     }
 474 }