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

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

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

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

jjg@1521 1 /*
darcy@1534 2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
jjg@1521 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jjg@1521 4 *
jjg@1521 5 * This code is free software; you can redistribute it and/or modify it
jjg@1521 6 * under the terms of the GNU General Public License version 2 only, as
jjg@1521 7 * published by the Free Software Foundation.
jjg@1521 8 *
jjg@1521 9 * This code is distributed in the hope that it will be useful, but WITHOUT
jjg@1521 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jjg@1521 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
jjg@1521 12 * version 2 for more details (a copy is included in the LICENSE file that
jjg@1521 13 * accompanied this code).
jjg@1521 14 *
jjg@1521 15 * You should have received a copy of the GNU General Public License version
jjg@1521 16 * 2 along with this work; if not, write to the Free Software Foundation,
jjg@1521 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jjg@1521 18 *
jjg@1521 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jjg@1521 20 * or visit www.oracle.com if you need additional information or have any
jjg@1521 21 * questions.
jjg@1521 22 */
jjg@1521 23
jjg@1521 24 /*
jjg@1521 25 * @test
jjg@1521 26 * @bug 8005085 8005877 8004829 8005681 8006734 8006775
jjg@1521 27 * @summary Combinations of Target ElementTypes on (repeated)type annotations.
jjg@1521 28 */
jjg@1521 29
jjg@1521 30 import com.sun.tools.classfile.*;
jjg@1521 31 import java.io.File;
jjg@1521 32
jjg@1521 33 public class CombinationsTargetTest1 extends ClassfileTestHelper {
jjg@1755 34
jjg@1755 35 // Test count helps identify test case in event of failure.
jjg@1521 36 int testcount = 0;
jjg@1755 37
jjg@1755 38 // Base test case template descriptions
jjg@1755 39 enum srce {
jjg@1755 40 src1("(repeating) type annotations at class level"),
jjg@1755 41 src2("(repeating) type annotations on method"),
jjg@1755 42 src3("(repeating) type annotations on wildcard, type arguments in anonymous class"),
jjg@1755 43 src4("(repeating) type annotations on type parameters, bounds and type arguments on class decl"),
jjg@1755 44 src5("(repeating) type annotations on type parameters, bounds and type arguments on method"),
jjg@1755 45 src6("(repeating) type annotations on type parameters, bounds and type arguments in method");
jjg@1755 46
jjg@1755 47 String description;
jjg@1755 48
jjg@1755 49 srce(String desc) {
jjg@1755 50 this.description = this + ": " +desc;
jjg@1755 51 }
jjg@1755 52 }
jjg@1521 53
jjg@1521 54 String[] ETypes={"TYPE", "FIELD", "METHOD", "PARAMETER", "CONSTRUCTOR",
jjg@1521 55 "LOCAL_VARIABLE", "ANNOTATION_TYPE", "PACKAGE"};
jjg@1521 56
jjg@1521 57 // local class tests will have an inner class.
jjg@1521 58 Boolean hasInnerClass=false;
jjg@1521 59 String innerClassname="";
jjg@1521 60
jjg@1521 61 public static void main(String[] args) throws Exception {
jjg@1521 62 new CombinationsTargetTest1().run();
jjg@1521 63 }
jjg@1521 64
jjg@1521 65 void run() throws Exception {
jjg@1521 66 // Determines which repeat and order in source(ABMix).
jjg@1521 67 Boolean As= false, BDs=true, ABMix=false;
jjg@1521 68 int testrun=0;
jjg@1521 69 Boolean [][] bRepeat = new Boolean[][]{{false,false,false},//no repeats
jjg@1521 70 {true,false,false}, //repeat @A
jjg@1521 71 {false,true,false}, //repeat @B
jjg@1521 72 {true,true,false}, //repeat both
jjg@1521 73 {false,false,true} //repeat mix
jjg@1521 74 };
jjg@1521 75 for(Boolean[] bCombo : bRepeat) {
jjg@1521 76 As=bCombo[0]; BDs=bCombo[1]; ABMix=bCombo[2];
jjg@1521 77 for(String et : ETypes) {
jjg@1521 78 switch(et) {
jjg@1521 79 case "METHOD":
jjg@1755 80 test( 8, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src1);
jjg@1755 81 test(10, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src2);
jjg@1755 82 test( 6, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src3);
jjg@1755 83 test(10, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src5);
jjg@1755 84 test( 0, 8, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1);
jjg@1755 85 test( 0, 10, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src2);
jjg@1755 86 test( 0, 6, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src3);
jjg@1755 87 test( 0, 10, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src5);
jjg@1521 88 break;
jjg@1521 89 case "CONSTRUCTOR":
jjg@1521 90 case "FIELD":
jjg@1755 91 test( 8, 0, 4, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src1);
jjg@1755 92 test( 6, 0, 3, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src4);
jjg@1755 93 test( 9, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src6);
jjg@1755 94 test( 0, 8, 0, 4, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1);
jjg@1755 95 test( 0, 6, 0, 3, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src4);
jjg@1755 96 test( 0, 9, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src6);
jjg@1521 97 break;
jjg@1521 98 default:/*TYPE,PARAMETER,LOCAL_VARIABLE,ANNOTATION_TYPE,PACKAGE*/
jjg@1755 99 test( 8, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src1);
jjg@1755 100 test( 6, 0, 3, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src4);
jjg@1755 101 test( 0, 8, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1);
jjg@1755 102 test( 0, 6, 0, 3, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src4);
jjg@1521 103 }
jjg@1521 104 }
jjg@1521 105 }
jjg@1521 106 }
jjg@1521 107
jjg@1521 108 public void test(int tinv, int tvis, int inv, int vis, Boolean Arepeats,
jjg@1521 109 Boolean BDrepeats, Boolean ABmix, String rtn, String et2,
jjg@1755 110 Integer N, srce source) throws Exception {
jjg@1521 111 ++testcount;
jjg@1521 112 expected_tvisibles = tvis;
jjg@1521 113 expected_tinvisibles = tinv;
jjg@1521 114 expected_visibles = vis;
jjg@1521 115 expected_invisibles = inv;
jjg@1521 116 File testFile = null;
jjg@1521 117 String tname="Test" + N.toString();
jjg@1521 118 hasInnerClass=false;
jjg@1521 119 String testDef = "Test " + testcount + " parameters: tinv=" + tinv +
jjg@1521 120 ", tvis=" + tvis + ", inv=" + inv + ", vis=" + vis +
jjg@1521 121 ", Arepeats=" + Arepeats + ", BDrepeats=" + BDrepeats +
jjg@1521 122 ", ABmix=" + ABmix + ", retention: " + rtn + ", anno2: " +
jjg@1521 123 et2 + ", src=" + source;
jjg@1521 124
jjg@1521 125 println(testDef);
jjg@1521 126 // Create test source and File.
jjg@1521 127 String sourceString = sourceString(tname, rtn, et2, Arepeats,
jjg@1521 128 BDrepeats, ABmix, source);
jjg@1521 129 testFile = writeTestFile(tname+".java", sourceString);
jjg@1521 130 // Compile test source and read classfile.
jjg@1521 131 File classFile = null;
jjg@1521 132 try {
jjg@1521 133 classFile = compile(testFile);
jjg@1521 134 } catch (Error err) {
jjg@1521 135 System.err.println("Failed compile. Source:\n" + sourceString);
jjg@1521 136 throw err;
jjg@1521 137 }
jjg@1521 138 //if sourcString() set hasInnerClass it also set innerClassname.
jjg@1521 139 if(hasInnerClass) {
jjg@1521 140 StringBuffer sb = new StringBuffer(classFile.getAbsolutePath());
jjg@1755 141 classFile=new File(sb.insert(sb.lastIndexOf(".class"),
jjg@1755 142 innerClassname).toString());
jjg@1521 143 }
jjg@1521 144 ClassFile cf = ClassFile.read(classFile);
jjg@1521 145
jjg@1521 146 //Test class,fields and method counts.
jjg@1521 147 test(cf);
jjg@1521 148
jjg@1521 149 for (Field f : cf.fields) {
jjg@1521 150 test(cf, f);
jjg@1521 151 }
jjg@1521 152 for (Method m: cf.methods) {
jjg@1521 153 test(cf, m);
jjg@1521 154 }
jjg@1521 155 countAnnotations();
jjg@1521 156 if (errors > 0) {
jjg@1521 157 System.err.println( testDef );
jjg@1521 158 System.err.println( "Source:\n" + sourceString );
jjg@1521 159 throw new Exception( errors + " errors found" );
jjg@1521 160 }
jjg@1521 161 println("Pass");
jjg@1521 162 }
jjg@1521 163
jjg@1521 164 //
jjg@1521 165 // Source for test cases
jjg@1521 166 //
jjg@1521 167 String sourceString(String testname, String retentn, String annot2,
jjg@1521 168 Boolean Arepeats, Boolean BDrepeats, Boolean ABmix,
jjg@1755 169 srce src) {
jjg@1521 170
jjg@1521 171 String As = "@A", Bs = "@B", Ds = "@D";
jjg@1521 172 if(Arepeats) As = "@A @A";
jjg@1521 173 if(BDrepeats) {
jjg@1521 174 Bs = "@B @B";
jjg@1521 175 Ds = "@D @D";
jjg@1521 176 }
jjg@1521 177 if(ABmix) { As = "@A @B"; Bs = "@A @B"; Ds = "@D @D"; }
jjg@1521 178
jjg@1521 179 // Source to check for TYPE_USE and TYPE_PARAMETER annotations.
jjg@1521 180 // Source base (annotations) is same for all test cases.
jjg@1521 181 String source = new String();
jjg@1521 182 String imports = new String("import java.lang.annotation.*; \n" +
jjg@1521 183 "import static java.lang.annotation.RetentionPolicy.*; \n" +
jjg@1521 184 "import static java.lang.annotation.ElementType.*; \n" +
jjg@1521 185 "import java.util.List; \n" +
jjg@1521 186 "import java.util.HashMap; \n" +
jjg@1521 187 "import java.util.Map; \n\n");
jjg@1521 188
jjg@1521 189 String sourceBase = new String("@Retention("+retentn+")\n" +
jjg@1521 190 "@Target({TYPE_USE,_OTHER_})\n" +
darcy@1531 191 "@Repeatable( AC.class )\n" +
jjg@1521 192 "@interface A { }\n\n" +
jjg@1521 193
jjg@1521 194 "@Retention("+retentn+")\n" +
jjg@1521 195 "@Target({TYPE_USE,_OTHER_})\n" +
jjg@1521 196 "@interface AC { A[] value(); }\n\n" +
jjg@1521 197
jjg@1521 198 "@Retention("+retentn+")\n" +
jjg@1521 199 "@Target({TYPE_USE,_OTHER_})\n" +
darcy@1531 200 "@Repeatable( BC.class )\n" +
jjg@1521 201 "@interface B { }\n\n" +
jjg@1521 202
jjg@1521 203 "@Retention("+retentn+")\n" +
jjg@1521 204 "@Target({TYPE_USE,_OTHER_})\n" +
jjg@1521 205 "@interface BC { B[] value(); } \n\n" +
jjg@1521 206
jjg@1521 207 "@Retention("+retentn+")\n" +
jjg@1521 208 "@Target({TYPE_PARAMETER,_OTHER_})\n" +
jjg@1521 209 "@interface C { }\n\n" +
jjg@1521 210
jjg@1521 211 "@Retention("+retentn+")\n" +
jjg@1521 212 "@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" +
darcy@1531 213 "@Repeatable(DC.class)\n" +
jjg@1521 214 "@interface D { }\n\n" +
jjg@1521 215
jjg@1521 216 "@Retention("+retentn+")\n" +
jjg@1521 217 "@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" +
jjg@1755 218 "@interface DC { D[] value(); }\n");
jjg@1521 219
jjg@1521 220 // Test case sources with sample generated source.
jjg@1521 221 switch(src) {
jjg@1755 222 case src1: // repeating type annotations at class level
jjg@1521 223 /*
jjg@1521 224 * @A @B class Test1 {
jjg@1521 225 * @A @B Test1(){}
jjg@1521 226 * @A @B Integer i1 = 0;
jjg@1521 227 * String @A @B [] @A @B [] sa = null;
jjg@1521 228 * // type usage in method body
jjg@1521 229 * String test(Test1 this, String param, String ... vararg) {
jjg@1521 230 * Object o = new String [3];
jjg@1521 231 * return (String) null;
jjg@1521 232 * }}
jjg@1521 233 */
jjg@1521 234 source = new String(
jjg@1755 235 "// " + src.description + "\n" +
jjg@1755 236 "_As_ _Bs_ class " + testname + " {\n" +
jjg@1755 237 "_As_ _Bs_ " + testname +"(){} \n" +
jjg@1755 238 "_As_ _Bs_ Integer i1 = 0; \n" +
jjg@1755 239 "String _As_ _Bs_ [] _As_ _Bs_ [] sa = null; \n" +
jjg@1755 240 "// type usage in method body \n" +
jjg@1755 241 "String test("+testname+" this, " +
jjg@1755 242 "String param, String ... vararg) { \n" +
jjg@1755 243 " Object o = new String [3]; \n" +
jjg@1755 244 " return (String) null; \n" +
jjg@1755 245 "}\n" +
jjg@1755 246 "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
jjg@1755 247 "\n";
jjg@1521 248 break;
jjg@1755 249 case src2: // (repeating) type annotations on method.
jjg@1521 250 /*
jjg@1521 251 * class Test12 {
jjg@1521 252 * Test12(){}
jjg@1521 253 * // type usage on method
jjg@1521 254 * @A @B String test(@A @B Test12 this, @A @B String param, @A @B String @A @B ... vararg) {
jjg@1521 255 * Object o = new String [3];
jjg@1521 256 * return (String) null;
jjg@1521 257 * }}
jjg@1521 258 */
jjg@1521 259 source = new String(
jjg@1755 260 "// " + src.description + "\n" +
jjg@1755 261 "class " + testname + " {\n" +
jjg@1755 262 testname +"(){} \n" +
jjg@1755 263 "// type usage on method \n" +
jjg@1755 264 "_As_ _Bs_ String test(_As_ _Bs_ "+testname+" this, " +
jjg@1755 265 "_As_ _Bs_ String param, _As_ _Bs_ String _As_ _Bs_ ... vararg) { \n" +
jjg@1755 266 " Object o = new String [3]; \n" +
jjg@1755 267 " return (String) null; \n" +
jjg@1755 268 "}\n" +
jjg@1755 269 "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
jjg@1755 270 "\n";
jjg@1521 271 break;
jjg@1755 272 case src3: //(repeating) annotations on wildcard, type arguments in anonymous class.
jjg@1521 273 /*
jjg@1521 274 * class Test13<T extends Object> {
jjg@1521 275 * public T data = null;
jjg@1521 276 * T getData() { return data;}
jjg@1521 277 * String mtest( Test13<String> t){ return t.getData(); }
jjg@1521 278 * public void test() {
jjg@1755 279 * mtest( new Test13<String>() {
jjg@1521 280 * void m1(List<@A @B ? extends @A @B Object> lst) {}
jjg@1521 281 * void m2() throws@A @B Exception { }
jjg@1521 282 * });
jjg@1521 283 * }
jjg@1521 284 * }
jjg@1521 285 */
jjg@1521 286 source = new String( source +
jjg@1755 287 "// " + src.description + "\n" +
jjg@1755 288 "class " + testname + "<T extends Object> {\n" +
jjg@1755 289 " public T data = null;\n" +
jjg@1755 290 " T getData() { return data;}\n" +
jjg@1755 291 " String mtest( " + testname + "<String> t){ return t.getData(); }\n" +
jjg@1755 292 " public void test() {\n" +
jjg@1755 293 " mtest( new " + testname + "<String>() {\n" +
jjg@1755 294 " void m1(List<_As_ _Bs_ ? extends _As_ _Bs_ Object> lst) {}\n" +
jjg@1755 295 " void m2() throws_As_ _Bs_ Exception { }\n" +
jjg@1755 296 " });\n" +
jjg@1755 297 " }\n" +
jjg@1755 298 "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
jjg@1755 299 "\n";
jjg@1755 300 hasInnerClass=true;
jjg@1755 301 innerClassname="$1";
jjg@1521 302 break;
jjg@1755 303 case src4: // (repeating)annotations on type parameters, bounds and type arguments on class decl.
jjg@1521 304 /*
jjg@1521 305 * @A @B @D
jjg@1521 306 * class Test2<@A @B @C @D T extends @A @B Object> {
jjg@1521 307 * Map<List<String>, Integer> map =
jjg@1521 308 * new HashMap<List< String>, Integer>();
jjg@1521 309 * Map<List<String>,Integer> map2 = new HashMap<>();
jjg@1521 310 * String test(Test2<T> this) { return null;}
jjg@1521 311 * <T> String genericMethod(T t) { return null; }
jjg@1521 312 * }
jjg@1521 313 */
jjg@1521 314 source = new String( source +
jjg@1755 315 "// " + src.description + "\n" +
jjg@1755 316 "_As_ _Bs_ _Ds_\n" + //8004829: A and B on type parameter below.
jjg@1755 317 "class " + testname + "<_As_ _Bs_ @C _Ds_ T extends _As_ _Bs_ Object> {\n" +
jjg@1755 318 " Map<List<String>, Integer> map =\n" +
jjg@1755 319 " new HashMap<List< String>, Integer>();\n" +
jjg@1755 320 " Map<List<String>,Integer> map2 = new HashMap<>();\n" +
jjg@1755 321 " String test(" + testname + "<T> this) { return null;}\n" +
jjg@1755 322 " <T> String genericMethod(T t) { return null; }\n" +
jjg@1755 323 "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
jjg@1755 324 "\n";
jjg@1755 325 break;
jjg@1755 326 case src5: // (repeating) annotations on type parameters, bounds and type arguments on method.
jjg@1521 327 /*
jjg@1521 328 * class Test14<T extends Object> {
jjg@1521 329 * Map<List<String>, Integer> map =
jjg@1521 330 * new HashMap<List<String>, Integer>();
jjg@1521 331 * Map<List<String>, Integer> map2 = new HashMap<>();
jjg@1521 332 * String test(@A @B Test14<@D T> this) { return null;}
jjg@1521 333 * <@C @D T> @A @B String genericMethod(@A @B @D T t) { return null; }
jjg@1521 334 * }
jjg@1521 335 */
jjg@1521 336 source = new String( source +
jjg@1755 337 "// " + src.description + "\n" +
jjg@1755 338 "class " + testname + "<T extends Object> {\n" +
jjg@1755 339 " Map<List<String>, Integer> map =\n" +
jjg@1755 340 " new HashMap<List<String>, Integer>();\n" +
jjg@1755 341 " Map<List<String>, Integer> map2 = new HashMap<>();\n" +
jjg@1755 342 " String test(_As_ _Bs_ " + testname + "<_Ds_ T> this) { return null;}\n" +
jjg@1755 343 " <@C _Ds_ T> _As_ _Bs_ String genericMethod(_As_ _Bs_ _Ds_ T t) { return null; }\n" +
jjg@1755 344 "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
jjg@1755 345 "\n";
jjg@1755 346 break;
jjg@1755 347 case src6: // repeating annotations on type parameters, bounds and type arguments in method.
jjg@1521 348 /*
jjg@1521 349 * class Test7{
jjg@1521 350 * <E extends Comparable> Map<List<E>, E > foo(E e) {
jjg@1521 351 * class maptest <@A @B @D E> {
jjg@1521 352 * Map<List<@A @B @D E>,@A @B @D E> getMap() {
jjg@1521 353 * return new HashMap<List<E>,E>();
jjg@1521 354 * }
jjg@1521 355 * }
jjg@1521 356 * return new maptest<E>().getMap();
jjg@1521 357 * }
jjg@1521 358 * Map<List<String>,String> shm = foo(new String("hello"));
jjg@1521 359 * }
jjg@1521 360 */
jjg@1521 361 source = new String( source +
jjg@1755 362 "// " + src.description + "\n" +
jjg@1755 363 "class "+ testname + "{\n" +
jjg@1755 364 " <E extends Comparable> Map<List<E>, E > foo(E e) {\n" +
jjg@1755 365 " class maptest <_As_ _Bs_ _Ds_ E> {\n" + // inner class $1maptest
jjg@1755 366 " Map<List<_As_ _Bs_ _Ds_ E>,_As_ _Bs_ _Ds_ E> getMap() { \n" +
jjg@1755 367 " return new HashMap<List<E>,E>();\n" +
jjg@1755 368 " }\n" +
jjg@1755 369 " }\n" +
jjg@1755 370 " return new maptest<E>().getMap();\n" +
jjg@1755 371 " }\n" +
jjg@1755 372 " Map<List<String>,String> shm = foo(new String(\"hello\"));\n" +
jjg@1755 373 "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
jjg@1755 374 "\n";
jjg@1755 375 hasInnerClass=true;
jjg@1755 376 innerClassname="$1maptest";
jjg@1755 377 break;
jjg@1521 378 }
jjg@1521 379 return imports + source;
jjg@1521 380 }
jjg@1521 381 }

mercurial