1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javap/AnnotationWriter.java Wed Apr 27 01:34:52 2016 +0800 1.3 @@ -0,0 +1,292 @@ 1.4 +/* 1.5 + * Copyright (c) 2007, 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. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +package com.sun.tools.javap; 1.30 + 1.31 +import com.sun.tools.classfile.Annotation; 1.32 +import com.sun.tools.classfile.TypeAnnotation; 1.33 +import com.sun.tools.classfile.Annotation.Annotation_element_value; 1.34 +import com.sun.tools.classfile.Annotation.Array_element_value; 1.35 +import com.sun.tools.classfile.Annotation.Class_element_value; 1.36 +import com.sun.tools.classfile.Annotation.Enum_element_value; 1.37 +import com.sun.tools.classfile.Annotation.Primitive_element_value; 1.38 +import com.sun.tools.classfile.ConstantPool; 1.39 +import com.sun.tools.classfile.ConstantPoolException; 1.40 +import com.sun.tools.classfile.Descriptor; 1.41 +import com.sun.tools.classfile.Descriptor.InvalidDescriptor; 1.42 + 1.43 +/** 1.44 + * A writer for writing annotations as text. 1.45 + * 1.46 + * <p><b>This is NOT part of any supported API. 1.47 + * If you write code that depends on this, you do so at your own risk. 1.48 + * This code and its internal interfaces are subject to change or 1.49 + * deletion without notice.</b> 1.50 + */ 1.51 +public class AnnotationWriter extends BasicWriter { 1.52 + static AnnotationWriter instance(Context context) { 1.53 + AnnotationWriter instance = context.get(AnnotationWriter.class); 1.54 + if (instance == null) 1.55 + instance = new AnnotationWriter(context); 1.56 + return instance; 1.57 + } 1.58 + 1.59 + protected AnnotationWriter(Context context) { 1.60 + super(context); 1.61 + classWriter = ClassWriter.instance(context); 1.62 + constantWriter = ConstantWriter.instance(context); 1.63 + } 1.64 + 1.65 + public void write(Annotation annot) { 1.66 + write(annot, false); 1.67 + } 1.68 + 1.69 + public void write(Annotation annot, boolean resolveIndices) { 1.70 + writeDescriptor(annot.type_index, resolveIndices); 1.71 + boolean showParens = annot.num_element_value_pairs > 0 || !resolveIndices; 1.72 + if (showParens) 1.73 + print("("); 1.74 + for (int i = 0; i < annot.num_element_value_pairs; i++) { 1.75 + if (i > 0) 1.76 + print(","); 1.77 + write(annot.element_value_pairs[i], resolveIndices); 1.78 + } 1.79 + if (showParens) 1.80 + print(")"); 1.81 + } 1.82 + 1.83 + public void write(TypeAnnotation annot) { 1.84 + write(annot, true, false); 1.85 + } 1.86 + 1.87 + public void write(TypeAnnotation annot, boolean showOffsets, boolean resolveIndices) { 1.88 + write(annot.annotation, resolveIndices); 1.89 + print(": "); 1.90 + write(annot.position, showOffsets); 1.91 + } 1.92 + 1.93 + public void write(TypeAnnotation.Position pos, boolean showOffsets) { 1.94 + print(pos.type); 1.95 + 1.96 + switch (pos.type) { 1.97 + // instanceof 1.98 + case INSTANCEOF: 1.99 + // new expression 1.100 + case NEW: 1.101 + // constructor/method reference receiver 1.102 + case CONSTRUCTOR_REFERENCE: 1.103 + case METHOD_REFERENCE: 1.104 + if (showOffsets) { 1.105 + print(", offset="); 1.106 + print(pos.offset); 1.107 + } 1.108 + break; 1.109 + // local variable 1.110 + case LOCAL_VARIABLE: 1.111 + // resource variable 1.112 + case RESOURCE_VARIABLE: 1.113 + if (pos.lvarOffset == null) { 1.114 + print(", lvarOffset is Null!"); 1.115 + break; 1.116 + } 1.117 + print(", {"); 1.118 + for (int i = 0; i < pos.lvarOffset.length; ++i) { 1.119 + if (i != 0) print("; "); 1.120 + if (showOffsets) { 1.121 + print("start_pc="); 1.122 + print(pos.lvarOffset[i]); 1.123 + } 1.124 + print(", length="); 1.125 + print(pos.lvarLength[i]); 1.126 + print(", index="); 1.127 + print(pos.lvarIndex[i]); 1.128 + } 1.129 + print("}"); 1.130 + break; 1.131 + // exception parameter 1.132 + case EXCEPTION_PARAMETER: 1.133 + print(", exception_index="); 1.134 + print(pos.exception_index); 1.135 + break; 1.136 + // method receiver 1.137 + case METHOD_RECEIVER: 1.138 + // Do nothing 1.139 + break; 1.140 + // type parameter 1.141 + case CLASS_TYPE_PARAMETER: 1.142 + case METHOD_TYPE_PARAMETER: 1.143 + print(", param_index="); 1.144 + print(pos.parameter_index); 1.145 + break; 1.146 + // type parameter bound 1.147 + case CLASS_TYPE_PARAMETER_BOUND: 1.148 + case METHOD_TYPE_PARAMETER_BOUND: 1.149 + print(", param_index="); 1.150 + print(pos.parameter_index); 1.151 + print(", bound_index="); 1.152 + print(pos.bound_index); 1.153 + break; 1.154 + // class extends or implements clause 1.155 + case CLASS_EXTENDS: 1.156 + print(", type_index="); 1.157 + print(pos.type_index); 1.158 + break; 1.159 + // throws 1.160 + case THROWS: 1.161 + print(", type_index="); 1.162 + print(pos.type_index); 1.163 + break; 1.164 + // method parameter 1.165 + case METHOD_FORMAL_PARAMETER: 1.166 + print(", param_index="); 1.167 + print(pos.parameter_index); 1.168 + break; 1.169 + // type cast 1.170 + case CAST: 1.171 + // method/constructor/reference type argument 1.172 + case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: 1.173 + case METHOD_INVOCATION_TYPE_ARGUMENT: 1.174 + case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT: 1.175 + case METHOD_REFERENCE_TYPE_ARGUMENT: 1.176 + if (showOffsets) { 1.177 + print(", offset="); 1.178 + print(pos.offset); 1.179 + } 1.180 + print(", type_index="); 1.181 + print(pos.type_index); 1.182 + break; 1.183 + // We don't need to worry about these 1.184 + case METHOD_RETURN: 1.185 + case FIELD: 1.186 + break; 1.187 + case UNKNOWN: 1.188 + throw new AssertionError("AnnotationWriter: UNKNOWN target type should never occur!"); 1.189 + default: 1.190 + throw new AssertionError("AnnotationWriter: Unknown target type for position: " + pos); 1.191 + } 1.192 + 1.193 + // Append location data for generics/arrays. 1.194 + if (!pos.location.isEmpty()) { 1.195 + print(", location="); 1.196 + print(pos.location); 1.197 + } 1.198 + } 1.199 + 1.200 + public void write(Annotation.element_value_pair pair) { 1.201 + write(pair, false); 1.202 + } 1.203 + 1.204 + public void write(Annotation.element_value_pair pair, boolean resolveIndices) { 1.205 + writeIndex(pair.element_name_index, resolveIndices); 1.206 + print("="); 1.207 + write(pair.value, resolveIndices); 1.208 + } 1.209 + 1.210 + public void write(Annotation.element_value value) { 1.211 + write(value, false); 1.212 + } 1.213 + 1.214 + public void write(Annotation.element_value value, boolean resolveIndices) { 1.215 + ev_writer.write(value, resolveIndices); 1.216 + } 1.217 + 1.218 + private void writeDescriptor(int index, boolean resolveIndices) { 1.219 + if (resolveIndices) { 1.220 + try { 1.221 + ConstantPool constant_pool = classWriter.getClassFile().constant_pool; 1.222 + Descriptor d = new Descriptor(index); 1.223 + print(d.getFieldType(constant_pool)); 1.224 + return; 1.225 + } catch (ConstantPoolException ignore) { 1.226 + } catch (InvalidDescriptor ignore) { 1.227 + } 1.228 + } 1.229 + 1.230 + print("#" + index); 1.231 + } 1.232 + 1.233 + private void writeIndex(int index, boolean resolveIndices) { 1.234 + if (resolveIndices) { 1.235 + print(constantWriter.stringValue(index)); 1.236 + } else 1.237 + print("#" + index); 1.238 + } 1.239 + 1.240 + element_value_Writer ev_writer = new element_value_Writer(); 1.241 + 1.242 + class element_value_Writer implements Annotation.element_value.Visitor<Void,Boolean> { 1.243 + public void write(Annotation.element_value value, boolean resolveIndices) { 1.244 + value.accept(this, resolveIndices); 1.245 + } 1.246 + 1.247 + public Void visitPrimitive(Primitive_element_value ev, Boolean resolveIndices) { 1.248 + if (resolveIndices) 1.249 + writeIndex(ev.const_value_index, resolveIndices); 1.250 + else 1.251 + print(((char) ev.tag) + "#" + ev.const_value_index); 1.252 + return null; 1.253 + } 1.254 + 1.255 + public Void visitEnum(Enum_element_value ev, Boolean resolveIndices) { 1.256 + if (resolveIndices) { 1.257 + writeIndex(ev.type_name_index, resolveIndices); 1.258 + print("."); 1.259 + writeIndex(ev.const_name_index, resolveIndices); 1.260 + } else 1.261 + print(((char) ev.tag) + "#" + ev.type_name_index + ".#" + ev.const_name_index); 1.262 + return null; 1.263 + } 1.264 + 1.265 + public Void visitClass(Class_element_value ev, Boolean resolveIndices) { 1.266 + if (resolveIndices) { 1.267 + writeIndex(ev.class_info_index, resolveIndices); 1.268 + print(".class"); 1.269 + } else 1.270 + print(((char) ev.tag) + "#" + ev.class_info_index); 1.271 + return null; 1.272 + } 1.273 + 1.274 + public Void visitAnnotation(Annotation_element_value ev, Boolean resolveIndices) { 1.275 + print((char) ev.tag); 1.276 + AnnotationWriter.this.write(ev.annotation_value, resolveIndices); 1.277 + return null; 1.278 + } 1.279 + 1.280 + public Void visitArray(Array_element_value ev, Boolean resolveIndices) { 1.281 + print("["); 1.282 + for (int i = 0; i < ev.num_values; i++) { 1.283 + if (i > 0) 1.284 + print(","); 1.285 + write(ev.values[i], resolveIndices); 1.286 + } 1.287 + print("]"); 1.288 + return null; 1.289 + } 1.290 + 1.291 + } 1.292 + 1.293 + private ClassWriter classWriter; 1.294 + private ConstantWriter constantWriter; 1.295 +}