Tue, 15 Oct 2013 15:57:13 -0700
8026564: import changes from type-annotations forest
Reviewed-by: jjg
Contributed-by: wdietl@gmail.com, steve.sides@oracle.com
1 /*
2 * Copyright (c) 2012, 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 */
24 import java.lang.annotation.*;
25 import java.io.*;
26 import java.net.URL;
27 import java.util.List;
29 import com.sun.tools.classfile.*;
31 public class ClassfileTestHelper {
32 int expected_tinvisibles = 0;
33 int expected_tvisibles = 0;
34 int expected_invisibles = 0;
35 int expected_visibles = 0;
37 //Makes debugging much easier. Set to 'false' for less output.
38 public Boolean verbose = true;
39 void println(String msg) { if (verbose) System.out.println(msg); }
40 void print(String msg) { if (verbose) System.out.print(msg); }
42 File writeTestFile(String fname, String source) throws IOException {
43 File f = new File(fname);
44 PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
45 out.println(source);
46 out.close();
47 return f;
48 }
50 File compile(File f) {
51 int rc = com.sun.tools.javac.Main.compile(new String[] {
52 "-source", "1.8", "-g", f.getPath() });
53 if (rc != 0)
54 throw new Error("compilation failed. rc=" + rc);
55 String path = f.getPath();
56 return new File(path.substring(0, path.length() - 5) + ".class");
57 }
59 ClassFile getClassFile(String name) throws IOException, ConstantPoolException {
60 URL url = getClass().getResource(name);
61 InputStream in = url.openStream();
62 try {
63 return ClassFile.read(in);
64 } finally {
65 in.close();
66 }
67 }
69 ClassFile getClassFile(URL url) throws IOException, ConstantPoolException {
70 InputStream in = url.openStream();
71 try {
72 return ClassFile.read(in);
73 } finally {
74 in.close();
75 }
76 }
78 /************ Helper annotations counting methods ******************/
79 void test(ClassFile cf) {
80 test("CLASS",cf, null, null, Attribute.RuntimeVisibleTypeAnnotations, true);
81 test("CLASS",cf, null, null, Attribute.RuntimeInvisibleTypeAnnotations, false);
82 //RuntimeAnnotations since one annotation can result in two attributes.
83 test("CLASS",cf, null, null, Attribute.RuntimeVisibleAnnotations, true);
84 test("CLASS",cf, null, null, Attribute.RuntimeInvisibleAnnotations, false);
85 }
87 void test(ClassFile cf, Field f, Boolean local) {
88 if (!local) {
89 test("FIELD",cf, f, null, Attribute.RuntimeVisibleTypeAnnotations, true);
90 test("FIELD",cf, f, null, Attribute.RuntimeInvisibleTypeAnnotations, false);
91 test("FIELD",cf, f, null, Attribute.RuntimeVisibleAnnotations, true);
92 test("FIELD",cf, f, null, Attribute.RuntimeInvisibleAnnotations, false);
93 } else {
94 test("CODE",cf, f, null, Attribute.RuntimeVisibleTypeAnnotations, true);
95 test("CODE",cf, f, null, Attribute.RuntimeInvisibleTypeAnnotations, false);
96 test("CODE",cf, f, null, Attribute.RuntimeVisibleAnnotations, true);
97 test("CODE",cf, f, null, Attribute.RuntimeInvisibleAnnotations, false);
98 }
99 }
101 void test(ClassFile cf, Field f) {
102 test(cf, f, false);
103 }
105 // 'local' determines whether to look for annotations in code attribute or not.
106 void test(ClassFile cf, Method m, Boolean local) {
107 if (!local) {
108 test("METHOD",cf, null, m, Attribute.RuntimeVisibleTypeAnnotations, true);
109 test("METHOD",cf, null, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
110 test("METHOD",cf, null, m, Attribute.RuntimeVisibleAnnotations, true);
111 test("METHOD",cf, null, m, Attribute.RuntimeInvisibleAnnotations, false);
112 } else {
113 test("MCODE",cf, null, m, Attribute.RuntimeVisibleTypeAnnotations, true);
114 test("MCODE",cf, null, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
115 test("MCODE",cf, null, m, Attribute.RuntimeVisibleAnnotations, true);
116 test("MCODE",cf, null, m, Attribute.RuntimeInvisibleAnnotations, false);
117 }
118 }
120 // default to not looking in code attribute
121 void test(ClassFile cf, Method m ) {
122 test(cf, m, false);
123 }
125 // Test the result of Attributes.getIndex according to expectations
126 // encoded in the class/field/method name; increment annotations counts.
127 void test(String ttype, ClassFile cf, Field f, Method m, String annName, boolean visible) {
128 String testtype = ttype;
129 String name = null;
130 int index = -1;
131 Attribute attr = null;
132 Code_attribute cAttr = null;
133 boolean isTAattr = annName.contains("TypeAnnotations");
134 try {
135 switch(testtype) {
136 case "FIELD":
137 name = f.getName(cf.constant_pool);
138 index = f.attributes.getIndex(cf.constant_pool, annName);
139 if(index!= -1)
140 attr = f.attributes.get(index);
141 break;
142 case "CODE":
143 name = f.getName(cf.constant_pool);
144 //fetch index of and code attribute and annotations from code attribute.
145 index = cf.attributes.getIndex(cf.constant_pool, Attribute.Code);
146 if(index!= -1) {
147 attr = cf.attributes.get(index);
148 assert attr instanceof Code_attribute;
149 cAttr = (Code_attribute)attr;
150 index = cAttr.attributes.getIndex(cf.constant_pool, annName);
151 if(index!= -1)
152 attr = cAttr.attributes.get(index);
153 }
154 break;
155 case "METHOD":
156 name = m.getName(cf.constant_pool);
157 index = m.attributes.getIndex(cf.constant_pool, annName);
158 if(index!= -1)
159 attr = m.attributes.get(index);
160 break;
161 case "MCODE":
162 name = m.getName(cf.constant_pool);
163 //fetch index of and code attribute and annotations from code attribute.
164 index = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
165 if(index!= -1) {
166 attr = m.attributes.get(index);
167 assert attr instanceof Code_attribute;
168 cAttr = (Code_attribute)attr;
169 index = cAttr.attributes.getIndex(cf.constant_pool, annName);
170 if(index!= -1)
171 attr = cAttr.attributes.get(index);
172 }
173 break;
174 default:
175 name = cf.getName();
176 index = cf.attributes.getIndex(cf.constant_pool, annName);
177 if(index!= -1) attr = cf.attributes.get(index);
178 }
179 } catch(ConstantPoolException cpe) { cpe.printStackTrace(); }
181 if (index != -1) {
182 if(isTAattr) { //count RuntimeTypeAnnotations
183 RuntimeTypeAnnotations_attribute tAttr =
184 (RuntimeTypeAnnotations_attribute)attr;
185 println(testtype + ": " + name + ", " + annName + ": " +
186 tAttr.annotations.length );
187 if (tAttr.annotations.length > 0) {
188 for (int i = 0; i < tAttr.annotations.length; i++) {
189 println(" types:" + tAttr.annotations[i].position.type);
190 }
191 } else {
192 println("");
193 }
194 allt += tAttr.annotations.length;
195 if (visible)
196 tvisibles += tAttr.annotations.length;
197 else
198 tinvisibles += tAttr.annotations.length;
199 } else {
200 RuntimeAnnotations_attribute tAttr =
201 (RuntimeAnnotations_attribute)attr;
202 println(testtype + ": " + name + ", " + annName + ": " +
203 tAttr.annotations.length );
204 all += tAttr.annotations.length;
205 if (visible)
206 visibles += tAttr.annotations.length;
207 else
208 invisibles += tAttr.annotations.length;
209 }
210 }
211 }
213 void countAnnotations() {
214 errors=0;
215 int expected_allt = expected_tvisibles + expected_tinvisibles;
216 int expected_all = expected_visibles + expected_invisibles;
218 if (expected_allt != allt) {
219 errors++;
220 System.err.println("Failure: expected " + expected_allt +
221 " type annotations but found " + allt);
222 }
223 if (expected_all != all) {
224 errors++;
225 System.err.println("Failure: expected " + expected_all +
226 " annotations but found " + all);
227 }
228 if (expected_tvisibles != tvisibles) {
229 errors++;
230 System.err.println("Failure: expected " + expected_tvisibles +
231 " typevisible annotations but found " + tvisibles);
232 }
234 if (expected_tinvisibles != tinvisibles) {
235 errors++;
236 System.err.println("Failure: expected " + expected_tinvisibles +
237 " typeinvisible annotations but found " + tinvisibles);
238 }
239 allt=0;
240 tvisibles=0;
241 tinvisibles=0;
242 all=0;
243 visibles=0;
244 invisibles=0;
245 }
247 int errors;
248 int allt;
249 int tvisibles;
250 int tinvisibles;
251 int all;
252 int visibles;
253 int invisibles;
254 }