1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/test/tools/javac/annotations/typeAnnotations/classfile/TestNewCastArray.java Wed Apr 27 01:34:52 2016 +0800 1.3 @@ -0,0 +1,375 @@ 1.4 +/* 1.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + */ 1.26 + 1.27 +/* 1.28 + * @test 1.29 + * @bug 8005681 1.30 + * @summary Repeated annotations on new,array,cast. 1.31 + */ 1.32 +import java.lang.annotation.*; 1.33 +import java.io.*; 1.34 +import java.util.List; 1.35 +import com.sun.tools.classfile.*; 1.36 + 1.37 +import java.lang.annotation.*; 1.38 +import static java.lang.annotation.RetentionPolicy.*; 1.39 +import static java.lang.annotation.ElementType.*; 1.40 + 1.41 +public class TestNewCastArray { 1.42 + int errors = 0; 1.43 + List<String> failedTests = new java.util.LinkedList<>(); 1.44 + 1.45 + // 'b' tests fail with only even numbers of annotations (8005681). 1.46 + String[] testclasses = {"Test1", 1.47 + "Test2a", "Test3a", "Test4a", "Test5a", 1.48 + "Test2b", "Test3b", "Test4b", "Test5b" 1.49 + }; 1.50 + 1.51 + public static void main(String[] args) throws Exception { 1.52 + new TestNewCastArray().run(); 1.53 + } 1.54 + 1.55 + void check(String testcase, int expected, int actual) { 1.56 + String res = testcase + ": (expected) " + expected + ", " + actual + " (actual): "; 1.57 + if(expected == actual) { 1.58 + res = res.concat("PASS"); 1.59 + } else { 1.60 + errors++; 1.61 + res = res.concat("FAIL"); 1.62 + failedTests.add(res); 1.63 + } 1.64 + System.out.println(res); 1.65 + } 1.66 + 1.67 + void report() { 1.68 + if(errors!=0) { 1.69 + System.err.println("Failed tests: " + errors + 1.70 + "\nfailed test cases:\n"); 1.71 + for(String t: failedTests) 1.72 + System.err.println(" " + t); 1.73 + throw new RuntimeException("FAIL: There were test failures."); 1.74 + } else 1.75 + System.out.println("PASS"); 1.76 + } 1.77 + 1.78 + void test(String clazz, String ttype, ClassFile cf, Method m, Field f, 1.79 + String name, boolean codeattr) { 1.80 + int actual = 0; 1.81 + int expected = 0, cexpected = 0; 1.82 + int index = 0; 1.83 + String memberName = null; 1.84 + Attribute attr = null; 1.85 + Code_attribute cAttr = null; 1.86 + String testcase = "undefined"; 1.87 + try { 1.88 + switch(ttype) { 1.89 + case "METHOD": 1.90 + index = m.attributes.getIndex(cf.constant_pool, name); 1.91 + memberName = m.getName(cf.constant_pool); 1.92 + if(index != -1) 1.93 + attr = m.attributes.get(index); 1.94 + break; 1.95 + case "MCODE": 1.96 + memberName = m.getName(cf.constant_pool); 1.97 + //fetch index of and code attribute and annotations from code attribute. 1.98 + index = m.attributes.getIndex(cf.constant_pool, Attribute.Code); 1.99 + if(index!= -1) { 1.100 + attr = m.attributes.get(index); 1.101 + assert attr instanceof Code_attribute; 1.102 + cAttr = (Code_attribute)attr; 1.103 + index = cAttr.attributes.getIndex(cf.constant_pool, name); 1.104 + if(index!= -1) 1.105 + attr = cAttr.attributes.get(index); 1.106 + } 1.107 + break; 1.108 + case "FIELD": 1.109 + index = f.attributes.getIndex(cf.constant_pool, name); 1.110 + memberName = f.getName(cf.constant_pool); 1.111 + if(index != -1) 1.112 + attr = f.attributes.get(index); 1.113 + break; 1.114 + case "CODE": 1.115 + memberName = f.getName(cf.constant_pool); 1.116 + //fetch index of and code attribute and annotations from code attribute. 1.117 + index = cf.attributes.getIndex(cf.constant_pool, Attribute.Code); 1.118 + if(index!= -1) { 1.119 + attr = cf.attributes.get(index); 1.120 + assert attr instanceof Code_attribute; 1.121 + cAttr = (Code_attribute)attr; 1.122 + index = cAttr.attributes.getIndex(cf.constant_pool, name); 1.123 + if(index!= -1) 1.124 + attr = cAttr.attributes.get(index); 1.125 + } 1.126 + break; 1.127 + default: 1.128 + break; 1.129 + } 1.130 + } catch(ConstantPoolException cpe) { cpe.printStackTrace(); } 1.131 + testcase = clazz+" "+ttype + ": " + memberName + ", " + name; 1.132 + if(index != -1) { 1.133 + //count RuntimeTypeAnnotations 1.134 + assert attr instanceof RuntimeTypeAnnotations_attribute; 1.135 + RuntimeTypeAnnotations_attribute tAttr = 1.136 + (RuntimeTypeAnnotations_attribute)attr; 1.137 + actual += tAttr.annotations.length; 1.138 + } 1.139 + if(memberName.compareTo("<init>")==0) memberName=clazz+memberName; 1.140 + switch ( memberName ) { 1.141 + //METHOD: 1.142 + case "Test1<init>": expected=0; break; 1.143 + case "testr22_22": expected=4; break; 1.144 + case "testr11_11": expected=4; break; 1.145 + case "testr12_21": expected=4; break; 1.146 + case "testr20_02": expected=2; break; 1.147 + 1.148 + case "Test2a<init>": cexpected=0; break; 1.149 + case "test00_00_11_11": cexpected=4; break; 1.150 + case "test21_12_21_12": cexpected=8; break; 1.151 + case "test_new1": cexpected=2; break; 1.152 + case "test_new2": cexpected=2; break; 1.153 + case "test_cast1": cexpected=2; break; 1.154 + case "test_cast2": cexpected=2; break; 1.155 + 1.156 + case "Test2b<init>": cexpected=0; break; 1.157 + case "test20_02_20_02": cexpected=4; break; 1.158 + case "test22_22_22_22": cexpected=8; break; 1.159 + case "test_new3": cexpected=1; break; 1.160 + case "test_new4": cexpected=1; break; 1.161 + case "test_new5": cexpected=2; break; 1.162 + case "test_cast3": cexpected=1; break; 1.163 + case "test_cast4": cexpected=2; break; 1.164 + 1.165 + case "Test3a<init>": cexpected=10; break; 1.166 + case "SA_21_12c": cexpected = 0; break; 1.167 + case "SA_01_10c": expected = 0; break; 1.168 + case "SA_11_11c": expected = 0; break; 1.169 + 1.170 + case "Test3b<init>": cexpected=6; break; 1.171 + case "SA_22_22c": cexpected = 0; break; 1.172 + case "SA_20_02c": cexpected = 0; break; 1.173 + 1.174 + case "Test3c<init>": cexpected=8; break; 1.175 + case "SA_10_10": cexpected = 0; break; 1.176 + case "SA_10_01": cexpected = 0; break; 1.177 + case "SA_21_12": cexpected = 0; break; 1.178 + 1.179 + case "Test3d<init>": cexpected=6; break; 1.180 + case "SA_20_02": cexpected = 0; break; 1.181 + case "SA_22_22": cexpected = 0; break; 1.182 + 1.183 + case "Test4a<init>": cexpected=4; break; 1.184 + case "nS_21": cexpected = 0; break; 1.185 + case "nS_12": cexpected = 0; break; 1.186 + 1.187 + case "Test4b<init>": cexpected=4; break; 1.188 + case "nS20": cexpected = 0; break; 1.189 + case "nS02": cexpected = 0; break; 1.190 + case "nS22": cexpected = 0; break; 1.191 + 1.192 + case "Test5a<init>": cexpected=4; break; 1.193 + case "ci11": expected = 0; break; 1.194 + case "ci21": expected = 0; break; 1.195 + 1.196 + case "Test5b<init>": cexpected=3; break; 1.197 + case "ci2": expected = 0; break; 1.198 + case "ci22": expected = 0; break; 1.199 + 1.200 + default: expected = 0; break; 1.201 + } 1.202 + if(codeattr) 1.203 + check(testcase, cexpected, actual); 1.204 + else 1.205 + check(testcase, expected, actual); 1.206 + } 1.207 + 1.208 + public void run() { 1.209 + ClassFile cf = null; 1.210 + InputStream in = null; 1.211 + for( String clazz : testclasses) { 1.212 + String testclazz = "TestNewCastArray$" + clazz + ".class"; 1.213 + System.out.println("Testing " + testclazz); 1.214 + try { 1.215 + in = getClass().getResource(testclazz).openStream(); 1.216 + cf = ClassFile.read(in); 1.217 + in.close(); 1.218 + } catch(Exception e) { e.printStackTrace(); } 1.219 + 1.220 + if(clazz.startsWith("Test1")) { 1.221 + for (Field f: cf.fields) 1.222 + test(clazz, "FIELD", cf, null, f, Attribute.RuntimeVisibleTypeAnnotations, false); 1.223 + for (Method m: cf.methods) 1.224 + test(clazz, "METHOD", cf, m, null, Attribute.RuntimeVisibleTypeAnnotations, false); 1.225 + } else { 1.226 + for (Field f: cf.fields) 1.227 + test(clazz, "CODE", cf, null, f, Attribute.RuntimeVisibleTypeAnnotations, true); 1.228 + for (Method m: cf.methods) 1.229 + test(clazz, "MCODE", cf, m, null, Attribute.RuntimeVisibleTypeAnnotations, true); 1.230 + } 1.231 + } 1.232 + report(); 1.233 + } 1.234 + 1.235 + //////// test class ////////////////////////// 1.236 + // "Test1" not in code attribute. 1.237 + // on arrays on and in method return 1.238 + static class Test1 { 1.239 + Test1(){} 1.240 + // OK expect 5, got 5 1.241 + String @A @A @B @B[] @A @A @B @B [] testr22_22(Test1 this, String param, String ... vararg) { 1.242 + String [][] sarray = new String [2][2]; 1.243 + return sarray; 1.244 + } 1.245 + // OK expect 5, got 5 1.246 + String @A @B [] @A @B [] testr11_11(Test1 this, String param, String ... vararg) { 1.247 + String [][] sarray = new String [2][2]; 1.248 + return sarray; 1.249 + } 1.250 + // OK expect 5, got 5 1.251 + String @A @B @B []@B @B @A[] testr12_21(Test1 this, String param, String ... vararg) { 1.252 + String [][] sarray = new String [2][2]; 1.253 + return sarray; 1.254 + } 1.255 + // OK expect 3, got 3 1.256 + String @A @A [] @B @B [] testr20_02(Test1 this, String param, String ... vararg) { 1.257 + String [][] sarray = new String [2][2]; 1.258 + return sarray; 1.259 + } 1.260 + } 1.261 + 1.262 + // Inside method body (in method's code attribute) 1.263 + static class Test2a { 1.264 + Test2a(){} 1.265 + Object o = new Integer(1); 1.266 + // expect 4 1.267 + String[][] test00_00_11_11(Test2a this, String param, String ... vararg) { 1.268 + String [] [] sarray = new String @A @B[2] @A @B [2]; 1.269 + return sarray; 1.270 + } 1.271 + 1.272 + // expect 8 1.273 + String[][] test21_12_21_12(Test2a this, String param, String ... vararg) { 1.274 + String @A @A @B [] @A @B @B [] sarray = new String @A @A @B[2] @A @B @B [2]; 1.275 + return sarray; 1.276 + } 1.277 + 1.278 + void test_new1() { String nS_21 = new @A @A @B String("Hello"); } 1.279 + void test_new2() { String nS_12 = new @A @B @B String("Hello"); } 1.280 + void test_cast1() { String tcs11 = (@A @B String)o; } 1.281 + void test_cast2() { String tcs21 = (@A @A @B String)o; } 1.282 + } 1.283 + 1.284 + static class Test2b { 1.285 + Test2b(){} 1.286 + Object o = new Integer(1); 1.287 + // expect 4 1.288 + String[][] test20_02_20_02(Test2b this, String param, String ... vararg) { 1.289 + String @A @A [] @B @B [] sarray = new String @A @A[2] @B @B [2]; 1.290 + return sarray; 1.291 + } 1.292 + 1.293 + // expect 8 1.294 + String[][] test22_22_22_22(Test2b this, String param, String ... vararg) { 1.295 + String @A @A @B @B [] @A @A @B @B [] sarray = new String @A @A @B @B [2] @A @A @B @B [2]; 1.296 + return sarray; 1.297 + } 1.298 + 1.299 + void test_new3() { String nS20 = new @A @A String("Hello"); } 1.300 + void test_new4() { String nS02 = new @B @B String("Hello"); } 1.301 + void test_new5() { String nS22 = new @A @A @B @B String("Hello"); } 1.302 + void test_cast3() { String tcs2 = (@A @A String)o; } 1.303 + void test_cast4() { String tcs22 = (@A @A @B @B String)o;} 1.304 + } 1.305 + 1.306 + // array levels 1.307 + static class Test3a { 1.308 + Test3a(){} 1.309 + // expect 4+2+4=10 1.310 + String [][] SA_21_12c = new String @A @A @B [2] @A @B @B[2]; 1.311 + String [][] SA_01_10c = new String @B [2] @A [2]; 1.312 + String [][] SA_11_11c = new String @A @B [2] @A @B [2]; 1.313 + } 1.314 + 1.315 + static class Test3b { 1.316 + Test3b(){} 1.317 + // expect 4+2=6 1.318 + String [][] SA_22_22c = new String @A @A @B @B[2] @A @A @B @B[2]; 1.319 + String [][] SA_20_02c = new String @A @A [2] @B @B[2]; 1.320 + } 1.321 + static class Test3c { 1.322 + Test3c(){} 1.323 + // OK expect 4 1.324 + String @A [] @A[] SA_10_10 = new String [2][2]; 1.325 + String @A [] @B[] SA_10_01 = new String [2][2]; 1.326 + String @A @A @B[] @A @B @B [] SA_21_12 = new String [2][2]; 1.327 + } 1.328 + 1.329 + static class Test3d { 1.330 + Test3d(){} 1.331 + // OK expect 4 1.332 + String @A @A [] @B @B [] SA_20_02 = new String [2][2]; 1.333 + String @A @A @B @B[] @A @A @B @B [] SA_22_22 = new String [2][2]; 1.334 + } 1.335 + 1.336 + // on new 1.337 + static class Test4a { 1.338 + Test4a(){} 1.339 + // expect 2+2=4 1.340 + String nS_21 = new @A @A @B String("Hello"); 1.341 + String nS_12 = new @A @B @B String("Hello"); 1.342 + } 1.343 + 1.344 + static class Test4b { 1.345 + Test4b(){} 1.346 + // expect 1+1+2=4 1.347 + String nS20 = new @A @A String("Hello"); 1.348 + String nS02 = new @B @B String("Hello"); 1.349 + String nS22 = new @A @A @B @B String("Hello"); 1.350 + } 1.351 + 1.352 + // Cast expressions 1.353 + static class Test5a { 1.354 + Test5a(){} 1.355 + Object o = new Integer(1); 1.356 + // expect 2+2=4 1.357 + Integer ci11 = (@A @B Integer)o; // OK expect 3, got 3 1.358 + Integer ci21 = (@A @A @B Integer)o; // OK expect 3, got 3 1.359 + } 1.360 + 1.361 + static class Test5b { 1.362 + Test5b(){} 1.363 + Object o = new Integer(1); 1.364 + // Cast expressions 1.365 + // expect 1+2=3 1.366 + Integer ci2 = (@A @A Integer)o; // FAIL expect 2, got 1 1.367 + Integer ci22 = (@A @A @B @B Integer)o; // FAIL expect 3, got 1 1.368 + } 1.369 + 1.370 +@Retention(RUNTIME) @Target({TYPE_USE}) @Repeatable( AC.class ) @interface A { } 1.371 +@Retention(RUNTIME) @Target({TYPE_USE}) @Repeatable( BC.class ) @interface B { } 1.372 +@Retention(RUNTIME) @Target({FIELD}) @Repeatable( FC.class ) @interface F { } 1.373 +@Retention(RUNTIME) @Target({TYPE_USE}) @interface AC { A[] value(); } 1.374 +@Retention(RUNTIME) @Target({TYPE_USE}) @interface BC { B[] value(); } 1.375 +@Retention(RUNTIME) @Target({FIELD}) @interface FC { F[] value(); } 1.376 + 1.377 +} 1.378 +