Mon, 25 Mar 2013 16:55:14 -0700
8010521: jdk8 l10n resource file translation update 2
Reviewed-by: naoto, yhuang
1 /*
2 * Copyright (c) 2007, 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.tools.javap;
28 import com.sun.tools.classfile.Annotation;
29 import com.sun.tools.classfile.TypeAnnotation;
30 import com.sun.tools.classfile.Annotation.Annotation_element_value;
31 import com.sun.tools.classfile.Annotation.Array_element_value;
32 import com.sun.tools.classfile.Annotation.Class_element_value;
33 import com.sun.tools.classfile.Annotation.Enum_element_value;
34 import com.sun.tools.classfile.Annotation.Primitive_element_value;
35 import com.sun.tools.classfile.ConstantPool;
36 import com.sun.tools.classfile.ConstantPoolException;
37 import com.sun.tools.classfile.Descriptor;
38 import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
40 /**
41 * A writer for writing annotations as text.
42 *
43 * <p><b>This is NOT part of any supported API.
44 * If you write code that depends on this, you do so at your own risk.
45 * This code and its internal interfaces are subject to change or
46 * deletion without notice.</b>
47 */
48 public class AnnotationWriter extends BasicWriter {
49 static AnnotationWriter instance(Context context) {
50 AnnotationWriter instance = context.get(AnnotationWriter.class);
51 if (instance == null)
52 instance = new AnnotationWriter(context);
53 return instance;
54 }
56 protected AnnotationWriter(Context context) {
57 super(context);
58 classWriter = ClassWriter.instance(context);
59 constantWriter = ConstantWriter.instance(context);
60 }
62 public void write(Annotation annot) {
63 write(annot, false);
64 }
66 public void write(Annotation annot, boolean resolveIndices) {
67 writeDescriptor(annot.type_index, resolveIndices);
68 boolean showParens = annot.num_element_value_pairs > 0 || !resolveIndices;
69 if (showParens)
70 print("(");
71 for (int i = 0; i < annot.num_element_value_pairs; i++) {
72 if (i > 0)
73 print(",");
74 write(annot.element_value_pairs[i], resolveIndices);
75 }
76 if (showParens)
77 print(")");
78 }
80 public void write(TypeAnnotation annot) {
81 write(annot, true, false);
82 }
84 public void write(TypeAnnotation annot, boolean showOffsets, boolean resolveIndices) {
85 write(annot.annotation, resolveIndices);
86 print(": ");
87 write(annot.position, showOffsets);
88 }
90 public void write(TypeAnnotation.Position pos, boolean showOffsets) {
91 print(pos.type);
93 switch (pos.type) {
94 // instanceof
95 case INSTANCEOF:
96 // new expression
97 case NEW:
98 // constructor/method reference receiver
99 case CONSTRUCTOR_REFERENCE:
100 case METHOD_REFERENCE:
101 if (showOffsets) {
102 print(", offset=");
103 print(pos.offset);
104 }
105 break;
106 // local variable
107 case LOCAL_VARIABLE:
108 // resource variable
109 case RESOURCE_VARIABLE:
110 if (pos.lvarOffset == null) {
111 print(", lvarOffset is Null!");
112 break;
113 }
114 print(", {");
115 for (int i = 0; i < pos.lvarOffset.length; ++i) {
116 if (i != 0) print("; ");
117 if (showOffsets) {
118 print("start_pc=");
119 print(pos.lvarOffset[i]);
120 }
121 print(", length=");
122 print(pos.lvarLength[i]);
123 print(", index=");
124 print(pos.lvarIndex[i]);
125 }
126 print("}");
127 break;
128 // exception parameter
129 case EXCEPTION_PARAMETER:
130 print(", exception_index=");
131 print(pos.exception_index);
132 break;
133 // method receiver
134 case METHOD_RECEIVER:
135 // Do nothing
136 break;
137 // type parameter
138 case CLASS_TYPE_PARAMETER:
139 case METHOD_TYPE_PARAMETER:
140 print(", param_index=");
141 print(pos.parameter_index);
142 break;
143 // type parameter bound
144 case CLASS_TYPE_PARAMETER_BOUND:
145 case METHOD_TYPE_PARAMETER_BOUND:
146 print(", param_index=");
147 print(pos.parameter_index);
148 print(", bound_index=");
149 print(pos.bound_index);
150 break;
151 // class extends or implements clause
152 case CLASS_EXTENDS:
153 print(", type_index=");
154 print(pos.type_index);
155 break;
156 // throws
157 case THROWS:
158 print(", type_index=");
159 print(pos.type_index);
160 break;
161 // method parameter
162 case METHOD_FORMAL_PARAMETER:
163 print(", param_index=");
164 print(pos.parameter_index);
165 break;
166 // type cast
167 case CAST:
168 // method/constructor/reference type argument
169 case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
170 case METHOD_INVOCATION_TYPE_ARGUMENT:
171 case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
172 case METHOD_REFERENCE_TYPE_ARGUMENT:
173 if (showOffsets) {
174 print(", offset=");
175 print(pos.offset);
176 }
177 print(", type_index=");
178 print(pos.type_index);
179 break;
180 // We don't need to worry about these
181 case METHOD_RETURN:
182 case FIELD:
183 break;
184 case UNKNOWN:
185 throw new AssertionError("AnnotationWriter: UNKNOWN target type should never occur!");
186 default:
187 throw new AssertionError("AnnotationWriter: Unknown target type for position: " + pos);
188 }
190 // Append location data for generics/arrays.
191 if (!pos.location.isEmpty()) {
192 print(", location=");
193 print(pos.location);
194 }
195 }
197 public void write(Annotation.element_value_pair pair) {
198 write(pair, false);
199 }
201 public void write(Annotation.element_value_pair pair, boolean resolveIndices) {
202 writeIndex(pair.element_name_index, resolveIndices);
203 print("=");
204 write(pair.value, resolveIndices);
205 }
207 public void write(Annotation.element_value value) {
208 write(value, false);
209 }
211 public void write(Annotation.element_value value, boolean resolveIndices) {
212 ev_writer.write(value, resolveIndices);
213 }
215 private void writeDescriptor(int index, boolean resolveIndices) {
216 if (resolveIndices) {
217 try {
218 ConstantPool constant_pool = classWriter.getClassFile().constant_pool;
219 Descriptor d = new Descriptor(index);
220 print(d.getFieldType(constant_pool));
221 return;
222 } catch (ConstantPoolException ignore) {
223 } catch (InvalidDescriptor ignore) {
224 }
225 }
227 print("#" + index);
228 }
230 private void writeIndex(int index, boolean resolveIndices) {
231 if (resolveIndices) {
232 print(constantWriter.stringValue(index));
233 } else
234 print("#" + index);
235 }
237 element_value_Writer ev_writer = new element_value_Writer();
239 class element_value_Writer implements Annotation.element_value.Visitor<Void,Boolean> {
240 public void write(Annotation.element_value value, boolean resolveIndices) {
241 value.accept(this, resolveIndices);
242 }
244 public Void visitPrimitive(Primitive_element_value ev, Boolean resolveIndices) {
245 if (resolveIndices)
246 writeIndex(ev.const_value_index, resolveIndices);
247 else
248 print(((char) ev.tag) + "#" + ev.const_value_index);
249 return null;
250 }
252 public Void visitEnum(Enum_element_value ev, Boolean resolveIndices) {
253 if (resolveIndices) {
254 writeIndex(ev.type_name_index, resolveIndices);
255 print(".");
256 writeIndex(ev.const_name_index, resolveIndices);
257 } else
258 print(((char) ev.tag) + "#" + ev.type_name_index + ".#" + ev.const_name_index);
259 return null;
260 }
262 public Void visitClass(Class_element_value ev, Boolean resolveIndices) {
263 if (resolveIndices) {
264 writeIndex(ev.class_info_index, resolveIndices);
265 print(".class");
266 } else
267 print(((char) ev.tag) + "#" + ev.class_info_index);
268 return null;
269 }
271 public Void visitAnnotation(Annotation_element_value ev, Boolean resolveIndices) {
272 print((char) ev.tag);
273 AnnotationWriter.this.write(ev.annotation_value, resolveIndices);
274 return null;
275 }
277 public Void visitArray(Array_element_value ev, Boolean resolveIndices) {
278 print("[");
279 for (int i = 0; i < ev.num_values; i++) {
280 if (i > 0)
281 print(",");
282 write(ev.values[i], resolveIndices);
283 }
284 print("]");
285 return null;
286 }
288 }
290 private ClassWriter classWriter;
291 private ConstantWriter constantWriter;
292 }