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

Tue, 15 Oct 2013 15:57:13 -0700

author
jjg
date
Tue, 15 Oct 2013 15:57:13 -0700
changeset 2134
b0c086cd4520
parent 1755
ddb4a2bfcd82
child 2525
2eb010b6cb22
permissions
-rw-r--r--

8026564: import changes from type-annotations forest
Reviewed-by: jjg
Contributed-by: wdietl@gmail.com, steve.sides@oracle.com

jjg@1521 1 /*
darcy@1534 2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
jjg@1521 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jjg@1521 4 *
jjg@1521 5 * This code is free software; you can redistribute it and/or modify it
jjg@1521 6 * under the terms of the GNU General Public License version 2 only, as
jjg@1521 7 * published by the Free Software Foundation.
jjg@1521 8 *
jjg@1521 9 * This code is distributed in the hope that it will be useful, but WITHOUT
jjg@1521 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jjg@1521 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
jjg@1521 12 * version 2 for more details (a copy is included in the LICENSE file that
jjg@1521 13 * accompanied this code).
jjg@1521 14 *
jjg@1521 15 * You should have received a copy of the GNU General Public License version
jjg@1521 16 * 2 along with this work; if not, write to the Free Software Foundation,
jjg@1521 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jjg@1521 18 *
jjg@1521 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jjg@1521 20 * or visit www.oracle.com if you need additional information or have any
jjg@1521 21 * questions.
jjg@1521 22 */
jjg@1521 23
jjg@1521 24 import java.lang.annotation.*;
jjg@1521 25 import java.io.*;
jjg@1521 26 import java.net.URL;
jjg@1521 27 import java.util.List;
jjg@1521 28
jjg@1521 29 import com.sun.tools.classfile.*;
jjg@1521 30
jjg@1521 31 public class ClassfileTestHelper {
jjg@1521 32 int expected_tinvisibles = 0;
jjg@1521 33 int expected_tvisibles = 0;
jjg@1521 34 int expected_invisibles = 0;
jjg@1521 35 int expected_visibles = 0;
jjg@1521 36
jjg@1521 37 //Makes debugging much easier. Set to 'false' for less output.
jjg@1521 38 public Boolean verbose = true;
jjg@2134 39 void println(String msg) { if (verbose) System.out.println(msg); }
jjg@2134 40 void print(String msg) { if (verbose) System.out.print(msg); }
jjg@1521 41
jjg@1521 42 File writeTestFile(String fname, String source) throws IOException {
jjg@1521 43 File f = new File(fname);
jjg@1521 44 PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
jjg@1521 45 out.println(source);
jjg@1521 46 out.close();
jjg@1521 47 return f;
jjg@1521 48 }
jjg@1521 49
jjg@1521 50 File compile(File f) {
jjg@1521 51 int rc = com.sun.tools.javac.Main.compile(new String[] {
jjg@1521 52 "-source", "1.8", "-g", f.getPath() });
jjg@1521 53 if (rc != 0)
jjg@1521 54 throw new Error("compilation failed. rc=" + rc);
jjg@1521 55 String path = f.getPath();
jjg@1521 56 return new File(path.substring(0, path.length() - 5) + ".class");
jjg@1521 57 }
jjg@1521 58
jjg@1521 59 ClassFile getClassFile(String name) throws IOException, ConstantPoolException {
jjg@1521 60 URL url = getClass().getResource(name);
jjg@1521 61 InputStream in = url.openStream();
jjg@1521 62 try {
jjg@1521 63 return ClassFile.read(in);
jjg@1521 64 } finally {
jjg@1521 65 in.close();
jjg@1521 66 }
jjg@1521 67 }
jjg@1521 68
jjg@1521 69 ClassFile getClassFile(URL url) throws IOException, ConstantPoolException {
jjg@1755 70 InputStream in = url.openStream();
jjg@1755 71 try {
jjg@1755 72 return ClassFile.read(in);
jjg@1755 73 } finally {
jjg@1755 74 in.close();
jjg@1755 75 }
jjg@1521 76 }
jjg@1521 77
jjg@1521 78 /************ Helper annotations counting methods ******************/
jjg@1521 79 void test(ClassFile cf) {
jjg@1521 80 test("CLASS",cf, null, null, Attribute.RuntimeVisibleTypeAnnotations, true);
jjg@1521 81 test("CLASS",cf, null, null, Attribute.RuntimeInvisibleTypeAnnotations, false);
jjg@1521 82 //RuntimeAnnotations since one annotation can result in two attributes.
jjg@1521 83 test("CLASS",cf, null, null, Attribute.RuntimeVisibleAnnotations, true);
jjg@1521 84 test("CLASS",cf, null, null, Attribute.RuntimeInvisibleAnnotations, false);
jjg@1521 85 }
jjg@1521 86
jjg@1755 87 void test(ClassFile cf, Field f, Boolean local) {
jjg@1755 88 if (!local) {
jjg@1755 89 test("FIELD",cf, f, null, Attribute.RuntimeVisibleTypeAnnotations, true);
jjg@1755 90 test("FIELD",cf, f, null, Attribute.RuntimeInvisibleTypeAnnotations, false);
jjg@1755 91 test("FIELD",cf, f, null, Attribute.RuntimeVisibleAnnotations, true);
jjg@1755 92 test("FIELD",cf, f, null, Attribute.RuntimeInvisibleAnnotations, false);
jjg@1755 93 } else {
jjg@1755 94 test("CODE",cf, f, null, Attribute.RuntimeVisibleTypeAnnotations, true);
jjg@1755 95 test("CODE",cf, f, null, Attribute.RuntimeInvisibleTypeAnnotations, false);
jjg@1755 96 test("CODE",cf, f, null, Attribute.RuntimeVisibleAnnotations, true);
jjg@1755 97 test("CODE",cf, f, null, Attribute.RuntimeInvisibleAnnotations, false);
jjg@1755 98 }
jjg@1521 99 }
jjg@1521 100
jjg@1521 101 void test(ClassFile cf, Field f) {
jjg@1755 102 test(cf, f, false);
jjg@1521 103 }
jjg@1521 104
jjg@1755 105 // 'local' determines whether to look for annotations in code attribute or not.
jjg@1755 106 void test(ClassFile cf, Method m, Boolean local) {
jjg@1755 107 if (!local) {
jjg@1755 108 test("METHOD",cf, null, m, Attribute.RuntimeVisibleTypeAnnotations, true);
jjg@1755 109 test("METHOD",cf, null, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
jjg@1755 110 test("METHOD",cf, null, m, Attribute.RuntimeVisibleAnnotations, true);
jjg@1755 111 test("METHOD",cf, null, m, Attribute.RuntimeInvisibleAnnotations, false);
jjg@1755 112 } else {
jjg@1755 113 test("MCODE",cf, null, m, Attribute.RuntimeVisibleTypeAnnotations, true);
jjg@1755 114 test("MCODE",cf, null, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
jjg@1755 115 test("MCODE",cf, null, m, Attribute.RuntimeVisibleAnnotations, true);
jjg@1755 116 test("MCODE",cf, null, m, Attribute.RuntimeInvisibleAnnotations, false);
jjg@1755 117 }
jjg@1755 118 }
jjg@1755 119
jjg@1755 120 // default to not looking in code attribute
jjg@1755 121 void test(ClassFile cf, Method m ) {
jjg@1755 122 test(cf, m, false);
jjg@1755 123 }
jjg@1521 124
jjg@1521 125 // Test the result of Attributes.getIndex according to expectations
jjg@1521 126 // encoded in the class/field/method name; increment annotations counts.
jjg@1521 127 void test(String ttype, ClassFile cf, Field f, Method m, String annName, boolean visible) {
jjg@1521 128 String testtype = ttype;
jjg@1521 129 String name = null;
jjg@1521 130 int index = -1;
jjg@1521 131 Attribute attr = null;
jjg@1755 132 Code_attribute cAttr = null;
jjg@1521 133 boolean isTAattr = annName.contains("TypeAnnotations");
jjg@1521 134 try {
jjg@1521 135 switch(testtype) {
jjg@1521 136 case "FIELD":
jjg@1521 137 name = f.getName(cf.constant_pool);
jjg@1521 138 index = f.attributes.getIndex(cf.constant_pool, annName);
jjg@1755 139 if(index!= -1)
jjg@1755 140 attr = f.attributes.get(index);
jjg@1755 141 break;
jjg@1755 142 case "CODE":
jjg@1755 143 name = f.getName(cf.constant_pool);
jjg@1755 144 //fetch index of and code attribute and annotations from code attribute.
jjg@1755 145 index = cf.attributes.getIndex(cf.constant_pool, Attribute.Code);
jjg@1755 146 if(index!= -1) {
jjg@1755 147 attr = cf.attributes.get(index);
jjg@1755 148 assert attr instanceof Code_attribute;
jjg@1755 149 cAttr = (Code_attribute)attr;
jjg@1755 150 index = cAttr.attributes.getIndex(cf.constant_pool, annName);
jjg@1755 151 if(index!= -1)
jjg@1755 152 attr = cAttr.attributes.get(index);
jjg@1755 153 }
jjg@1521 154 break;
jjg@1521 155 case "METHOD":
jjg@1521 156 name = m.getName(cf.constant_pool);
jjg@1521 157 index = m.attributes.getIndex(cf.constant_pool, annName);
jjg@1755 158 if(index!= -1)
jjg@1755 159 attr = m.attributes.get(index);
jjg@1755 160 break;
jjg@1755 161 case "MCODE":
jjg@1755 162 name = m.getName(cf.constant_pool);
jjg@1755 163 //fetch index of and code attribute and annotations from code attribute.
jjg@1755 164 index = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
jjg@1755 165 if(index!= -1) {
jjg@1755 166 attr = m.attributes.get(index);
jjg@1755 167 assert attr instanceof Code_attribute;
jjg@1755 168 cAttr = (Code_attribute)attr;
jjg@1755 169 index = cAttr.attributes.getIndex(cf.constant_pool, annName);
jjg@1755 170 if(index!= -1)
jjg@1755 171 attr = cAttr.attributes.get(index);
jjg@1755 172 }
jjg@1521 173 break;
jjg@1521 174 default:
jjg@1521 175 name = cf.getName();
jjg@1521 176 index = cf.attributes.getIndex(cf.constant_pool, annName);
jjg@1521 177 if(index!= -1) attr = cf.attributes.get(index);
jjg@1521 178 }
jjg@1521 179 } catch(ConstantPoolException cpe) { cpe.printStackTrace(); }
jjg@1521 180
jjg@1521 181 if (index != -1) {
jjg@1521 182 if(isTAattr) { //count RuntimeTypeAnnotations
jjg@1521 183 RuntimeTypeAnnotations_attribute tAttr =
jjg@1521 184 (RuntimeTypeAnnotations_attribute)attr;
jjg@1521 185 println(testtype + ": " + name + ", " + annName + ": " +
jjg@1521 186 tAttr.annotations.length );
jjg@2134 187 if (tAttr.annotations.length > 0) {
jjg@2134 188 for (int i = 0; i < tAttr.annotations.length; i++) {
jjg@2134 189 println(" types:" + tAttr.annotations[i].position.type);
jjg@2134 190 }
jjg@2134 191 } else {
jjg@2134 192 println("");
jjg@2134 193 }
jjg@1521 194 allt += tAttr.annotations.length;
jjg@1521 195 if (visible)
jjg@1521 196 tvisibles += tAttr.annotations.length;
jjg@1521 197 else
jjg@1521 198 tinvisibles += tAttr.annotations.length;
jjg@1521 199 } else {
jjg@1521 200 RuntimeAnnotations_attribute tAttr =
jjg@1521 201 (RuntimeAnnotations_attribute)attr;
jjg@1521 202 println(testtype + ": " + name + ", " + annName + ": " +
jjg@1521 203 tAttr.annotations.length );
jjg@1521 204 all += tAttr.annotations.length;
jjg@1521 205 if (visible)
jjg@1521 206 visibles += tAttr.annotations.length;
jjg@1521 207 else
jjg@1521 208 invisibles += tAttr.annotations.length;
jjg@1521 209 }
jjg@1521 210 }
jjg@1521 211 }
jjg@1521 212
jjg@1521 213 void countAnnotations() {
jjg@1521 214 errors=0;
jjg@1521 215 int expected_allt = expected_tvisibles + expected_tinvisibles;
jjg@1521 216 int expected_all = expected_visibles + expected_invisibles;
jjg@1521 217
jjg@1521 218 if (expected_allt != allt) {
jjg@1521 219 errors++;
jjg@1521 220 System.err.println("Failure: expected " + expected_allt +
jjg@1521 221 " type annotations but found " + allt);
jjg@1521 222 }
jjg@1521 223 if (expected_all != all) {
jjg@1521 224 errors++;
jjg@1521 225 System.err.println("Failure: expected " + expected_all +
jjg@1521 226 " annotations but found " + all);
jjg@1521 227 }
jjg@1521 228 if (expected_tvisibles != tvisibles) {
jjg@1521 229 errors++;
jjg@1521 230 System.err.println("Failure: expected " + expected_tvisibles +
jjg@1521 231 " typevisible annotations but found " + tvisibles);
jjg@1521 232 }
jjg@1521 233
jjg@1521 234 if (expected_tinvisibles != tinvisibles) {
jjg@1521 235 errors++;
jjg@1521 236 System.err.println("Failure: expected " + expected_tinvisibles +
jjg@1521 237 " typeinvisible annotations but found " + tinvisibles);
jjg@1521 238 }
jjg@1521 239 allt=0;
jjg@1521 240 tvisibles=0;
jjg@1521 241 tinvisibles=0;
jjg@1521 242 all=0;
jjg@1521 243 visibles=0;
jjg@1521 244 invisibles=0;
jjg@1521 245 }
jjg@1521 246
jjg@1521 247 int errors;
jjg@1521 248 int allt;
jjg@1521 249 int tvisibles;
jjg@1521 250 int tinvisibles;
jjg@1521 251 int all;
jjg@1521 252 int visibles;
jjg@1521 253 int invisibles;
jjg@1521 254 }

mercurial