1 /*
2 * Copyright (c) 2013, 2015, 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 8005681
27 * @summary Repeated annotations on new,array,cast.
28 * @modules jdk.jdeps/com.sun.tools.classfile
29 */
30 import java.lang.annotation.*;
31 import java.io.*;
32 import java.util.List;
33 import com.sun.tools.classfile.*;
34
35 import java.lang.annotation.*;
36 import static java.lang.annotation.RetentionPolicy.*;
37 import static java.lang.annotation.ElementType.*;
38
39 public class TestNewCastArray {
40 int errors = 0;
41 List<String> failedTests = new java.util.LinkedList<>();
42
43 // 'b' tests fail with only even numbers of annotations (8005681).
44 String[] testclasses = {"Test1",
45 "Test2a", "Test3a", "Test4a", "Test5a",
46 "Test2b", "Test3b", "Test4b", "Test5b"
47 };
48
main(String[] args)49 public static void main(String[] args) throws Exception {
50 new TestNewCastArray().run();
51 }
52
check(String testcase, int expected, int actual)53 void check(String testcase, int expected, int actual) {
54 String res = testcase + ": (expected) " + expected + ", " + actual + " (actual): ";
55 if(expected == actual) {
56 res = res.concat("PASS");
57 } else {
58 errors++;
59 res = res.concat("FAIL");
60 failedTests.add(res);
61 }
62 System.out.println(res);
63 }
64
report()65 void report() {
66 if(errors!=0) {
67 System.err.println("Failed tests: " + errors +
68 "\nfailed test cases:\n");
69 for(String t: failedTests)
70 System.err.println(" " + t);
71 throw new RuntimeException("FAIL: There were test failures.");
72 } else
73 System.out.println("PASS");
74 }
75
test(String clazz, String ttype, ClassFile cf, Method m, Field f, String name, boolean codeattr)76 void test(String clazz, String ttype, ClassFile cf, Method m, Field f,
77 String name, boolean codeattr) {
78 int actual = 0;
79 int expected = 0, cexpected = 0;
80 int index = 0;
81 String memberName = null;
82 Attribute attr = null;
83 Code_attribute cAttr = null;
84 String testcase = "undefined";
85 try {
86 switch(ttype) {
87 case "METHOD":
88 index = m.attributes.getIndex(cf.constant_pool, name);
89 memberName = m.getName(cf.constant_pool);
90 if(index != -1)
91 attr = m.attributes.get(index);
92 break;
93 case "MCODE":
94 memberName = m.getName(cf.constant_pool);
95 //fetch index of and code attribute and annotations from code attribute.
96 index = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
97 if(index!= -1) {
98 attr = m.attributes.get(index);
99 assert attr instanceof Code_attribute;
100 cAttr = (Code_attribute)attr;
101 index = cAttr.attributes.getIndex(cf.constant_pool, name);
102 if(index!= -1)
103 attr = cAttr.attributes.get(index);
104 }
105 break;
106 case "FIELD":
107 index = f.attributes.getIndex(cf.constant_pool, name);
108 memberName = f.getName(cf.constant_pool);
109 if(index != -1)
110 attr = f.attributes.get(index);
111 break;
112 case "CODE":
113 memberName = f.getName(cf.constant_pool);
114 //fetch index of and code attribute and annotations from code attribute.
115 index = cf.attributes.getIndex(cf.constant_pool, Attribute.Code);
116 if(index!= -1) {
117 attr = cf.attributes.get(index);
118 assert attr instanceof Code_attribute;
119 cAttr = (Code_attribute)attr;
120 index = cAttr.attributes.getIndex(cf.constant_pool, name);
121 if(index!= -1)
122 attr = cAttr.attributes.get(index);
123 }
124 break;
125 default:
126 break;
127 }
128 } catch(ConstantPoolException cpe) { cpe.printStackTrace(); }
129 testcase = clazz+" "+ttype + ": " + memberName + ", " + name;
130 if(index != -1) {
131 //count RuntimeTypeAnnotations
132 assert attr instanceof RuntimeTypeAnnotations_attribute;
133 RuntimeTypeAnnotations_attribute tAttr =
134 (RuntimeTypeAnnotations_attribute)attr;
135 actual += tAttr.annotations.length;
136 }
137 if(memberName.compareTo("<init>")==0) memberName=clazz+memberName;
138 switch ( memberName ) {
139 //METHOD:
140 case "Test1<init>": expected=0; break;
141 case "testr22_22": expected=4; break;
142 case "testr11_11": expected=4; break;
143 case "testr12_21": expected=4; break;
144 case "testr20_02": expected=2; break;
145
146 case "Test2a<init>": cexpected=0; break;
147 case "test00_00_11_11": cexpected=4; break;
148 case "test21_12_21_12": cexpected=8; break;
149 case "test_new1": cexpected=2; break;
150 case "test_new2": cexpected=2; break;
151 case "test_cast1": cexpected=2; break;
152 case "test_cast2": cexpected=2; break;
153
154 case "Test2b<init>": cexpected=0; break;
155 case "test20_02_20_02": cexpected=4; break;
156 case "test22_22_22_22": cexpected=8; break;
157 case "test_new3": cexpected=1; break;
158 case "test_new4": cexpected=1; break;
159 case "test_new5": cexpected=2; break;
160 case "test_cast3": cexpected=1; break;
161 case "test_cast4": cexpected=2; break;
162
163 case "Test3a<init>": cexpected=10; break;
164 case "SA_21_12c": cexpected = 0; break;
165 case "SA_01_10c": expected = 0; break;
166 case "SA_11_11c": expected = 0; break;
167
168 case "Test3b<init>": cexpected=6; break;
169 case "SA_22_22c": cexpected = 0; break;
170 case "SA_20_02c": cexpected = 0; break;
171
172 case "Test3c<init>": cexpected=8; break;
173 case "SA_10_10": cexpected = 0; break;
174 case "SA_10_01": cexpected = 0; break;
175 case "SA_21_12": cexpected = 0; break;
176
177 case "Test3d<init>": cexpected=6; break;
178 case "SA_20_02": cexpected = 0; break;
179 case "SA_22_22": cexpected = 0; break;
180
181 case "Test4a<init>": cexpected=4; break;
182 case "nS_21": cexpected = 0; break;
183 case "nS_12": cexpected = 0; break;
184
185 case "Test4b<init>": cexpected=4; break;
186 case "nS20": cexpected = 0; break;
187 case "nS02": cexpected = 0; break;
188 case "nS22": cexpected = 0; break;
189
190 case "Test5a<init>": cexpected=4; break;
191 case "ci11": expected = 0; break;
192 case "ci21": expected = 0; break;
193
194 case "Test5b<init>": cexpected=3; break;
195 case "ci2": expected = 0; break;
196 case "ci22": expected = 0; break;
197
198 default: expected = 0; break;
199 }
200 if(codeattr)
201 check(testcase, cexpected, actual);
202 else
203 check(testcase, expected, actual);
204 }
205
run()206 public void run() {
207 ClassFile cf = null;
208 InputStream in = null;
209 for( String clazz : testclasses) {
210 String testclazz = "TestNewCastArray$" + clazz + ".class";
211 System.out.println("Testing " + testclazz);
212 try {
213 in = getClass().getResource(testclazz).openStream();
214 cf = ClassFile.read(in);
215 in.close();
216 } catch(Exception e) { e.printStackTrace(); }
217
218 if(clazz.startsWith("Test1")) {
219 for (Field f: cf.fields)
220 test(clazz, "FIELD", cf, null, f, Attribute.RuntimeVisibleTypeAnnotations, false);
221 for (Method m: cf.methods)
222 test(clazz, "METHOD", cf, m, null, Attribute.RuntimeVisibleTypeAnnotations, false);
223 } else {
224 for (Field f: cf.fields)
225 test(clazz, "CODE", cf, null, f, Attribute.RuntimeVisibleTypeAnnotations, true);
226 for (Method m: cf.methods)
227 test(clazz, "MCODE", cf, m, null, Attribute.RuntimeVisibleTypeAnnotations, true);
228 }
229 }
230 report();
231 }
232
233 //////// test class //////////////////////////
234 // "Test1" not in code attribute.
235 // on arrays on and in method return
236 static class Test1 {
Test1()237 Test1(){}
238 // OK expect 5, got 5
testr22_22(Test1 this, String param, String ... vararg)239 String @A @A @B @B[] @A @A @B @B [] testr22_22(Test1 this, String param, String ... vararg) {
240 String [][] sarray = new String [2][2];
241 return sarray;
242 }
243 // OK expect 5, got 5
testr11_11(Test1 this, String param, String ... vararg)244 String @A @B [] @A @B [] testr11_11(Test1 this, String param, String ... vararg) {
245 String [][] sarray = new String [2][2];
246 return sarray;
247 }
248 // OK expect 5, got 5
testr12_21(Test1 this, String param, String ... vararg)249 String @A @B @B []@B @B @A[] testr12_21(Test1 this, String param, String ... vararg) {
250 String [][] sarray = new String [2][2];
251 return sarray;
252 }
253 // OK expect 3, got 3
testr20_02(Test1 this, String param, String ... vararg)254 String @A @A [] @B @B [] testr20_02(Test1 this, String param, String ... vararg) {
255 String [][] sarray = new String [2][2];
256 return sarray;
257 }
258 }
259
260 // Inside method body (in method's code attribute)
261 static class Test2a {
Test2a()262 Test2a(){}
263 Object o = new Integer(1);
264 // expect 4
test00_00_11_11(Test2a this, String param, String ... vararg)265 String[][] test00_00_11_11(Test2a this, String param, String ... vararg) {
266 String [] [] sarray = new String @A @B[2] @A @B [2];
267 return sarray;
268 }
269
270 // expect 8
test21_12_21_12(Test2a this, String param, String ... vararg)271 String[][] test21_12_21_12(Test2a this, String param, String ... vararg) {
272 String @A @A @B [] @A @B @B [] sarray = new String @A @A @B[2] @A @B @B [2];
273 return sarray;
274 }
275
test_new1()276 void test_new1() { String nS_21 = new @A @A @B String("Hello"); }
test_new2()277 void test_new2() { String nS_12 = new @A @B @B String("Hello"); }
test_cast1()278 void test_cast1() { String tcs11 = (@A @B String)o; }
test_cast2()279 void test_cast2() { String tcs21 = (@A @A @B String)o; }
280 }
281
282 static class Test2b {
Test2b()283 Test2b(){}
284 Object o = new Integer(1);
285 // expect 4
test20_02_20_02(Test2b this, String param, String ... vararg)286 String[][] test20_02_20_02(Test2b this, String param, String ... vararg) {
287 String @A @A [] @B @B [] sarray = new String @A @A[2] @B @B [2];
288 return sarray;
289 }
290
291 // expect 8
test22_22_22_22(Test2b this, String param, String ... vararg)292 String[][] test22_22_22_22(Test2b this, String param, String ... vararg) {
293 String @A @A @B @B [] @A @A @B @B [] sarray = new String @A @A @B @B [2] @A @A @B @B [2];
294 return sarray;
295 }
296
test_new3()297 void test_new3() { String nS20 = new @A @A String("Hello"); }
test_new4()298 void test_new4() { String nS02 = new @B @B String("Hello"); }
test_new5()299 void test_new5() { String nS22 = new @A @A @B @B String("Hello"); }
test_cast3()300 void test_cast3() { String tcs2 = (@A @A String)o; }
test_cast4()301 void test_cast4() { String tcs22 = (@A @A @B @B String)o;}
302 }
303
304 // array levels
305 static class Test3a {
Test3a()306 Test3a(){}
307 // expect 4+2+4=10
308 String [][] SA_21_12c = new String @A @A @B [2] @A @B @B[2];
309 String [][] SA_01_10c = new String @B [2] @A [2];
310 String [][] SA_11_11c = new String @A @B [2] @A @B [2];
311 }
312
313 static class Test3b {
Test3b()314 Test3b(){}
315 // expect 4+2=6
316 String [][] SA_22_22c = new String @A @A @B @B[2] @A @A @B @B[2];
317 String [][] SA_20_02c = new String @A @A [2] @B @B[2];
318 }
319 static class Test3c {
Test3c()320 Test3c(){}
321 // OK expect 4
322 String @A [] @A[] SA_10_10 = new String [2][2];
323 String @A [] @B[] SA_10_01 = new String [2][2];
324 String @A @A @B[] @A @B @B [] SA_21_12 = new String [2][2];
325 }
326
327 static class Test3d {
Test3d()328 Test3d(){}
329 // OK expect 4
330 String @A @A [] @B @B [] SA_20_02 = new String [2][2];
331 String @A @A @B @B[] @A @A @B @B [] SA_22_22 = new String [2][2];
332 }
333
334 // on new
335 static class Test4a {
Test4a()336 Test4a(){}
337 // expect 2+2=4
338 String nS_21 = new @A @A @B String("Hello");
339 String nS_12 = new @A @B @B String("Hello");
340 }
341
342 static class Test4b {
Test4b()343 Test4b(){}
344 // expect 1+1+2=4
345 String nS20 = new @A @A String("Hello");
346 String nS02 = new @B @B String("Hello");
347 String nS22 = new @A @A @B @B String("Hello");
348 }
349
350 // Cast expressions
351 static class Test5a {
Test5a()352 Test5a(){}
353 Object o = new Integer(1);
354 // expect 2+2=4
355 Integer ci11 = (@A @B Integer)o; // OK expect 3, got 3
356 Integer ci21 = (@A @A @B Integer)o; // OK expect 3, got 3
357 }
358
359 static class Test5b {
Test5b()360 Test5b(){}
361 Object o = new Integer(1);
362 // Cast expressions
363 // expect 1+2=3
364 Integer ci2 = (@A @A Integer)o; // FAIL expect 2, got 1
365 Integer ci22 = (@A @A @B @B Integer)o; // FAIL expect 3, got 1
366 }
367
368 @Retention(RUNTIME) @Target({TYPE_USE}) @Repeatable( AC.class ) @interface A { }
369 @Retention(RUNTIME) @Target({TYPE_USE}) @Repeatable( BC.class ) @interface B { }
370 @Retention(RUNTIME) @Target({FIELD}) @Repeatable( FC.class ) @interface F { }
value()371 @Retention(RUNTIME) @Target({TYPE_USE}) @interface AC { A[] value(); }
value()372 @Retention(RUNTIME) @Target({TYPE_USE}) @interface BC { B[] value(); }
value()373 @Retention(RUNTIME) @Target({FIELD}) @interface FC { F[] value(); }
374
375 }
376
377