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

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

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

mercurial