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

changeset 0
959103a6100f
child 2801
31ceef045272
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 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;
46
47
48 import java.lang.annotation.*;
49 import static java.lang.annotation.RetentionPolicy.*;
50 import static java.lang.annotation.ElementType.*;
51
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"));
63
64 String[] AnnoAttributes = {
65 Attribute.RuntimeVisibleTypeAnnotations,
66 Attribute.RuntimeInvisibleTypeAnnotations,
67 Attribute.RuntimeVisibleAnnotations,
68 Attribute.RuntimeInvisibleAnnotations
69 };
70
71 // template for source files
72 String srcTemplate = "testanoninner.template";
73
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<>();
84
85 public static void main(String[] args) throws Exception {
86 new TestAnonInnerClasses().run();
87 }
88
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) {
93
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 }
136
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 }
147
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;
207
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 }
281
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 }
344
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 }
402
403
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 }
420
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";
432
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