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

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

mercurial