AttributeWriter.java revision 3792:d516975e8110
133965Sjdp/*
233965Sjdp * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
3218822Sdim * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
433965Sjdp *
5218822Sdim * This code is free software; you can redistribute it and/or modify it
633965Sjdp * under the terms of the GNU General Public License version 2 only, as
733965Sjdp * published by the Free Software Foundation.  Oracle designates this
8218822Sdim * particular file as subject to the "Classpath" exception as provided
9218822Sdim * by Oracle in the LICENSE file that accompanied this code.
10218822Sdim *
1133965Sjdp * This code is distributed in the hope that it will be useful, but WITHOUT
12218822Sdim * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13218822Sdim * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14218822Sdim * version 2 for more details (a copy is included in the LICENSE file that
15218822Sdim * accompanied this code).
16218822Sdim *
17218822Sdim * You should have received a copy of the GNU General Public License version
18218822Sdim * 2 along with this work; if not, write to the Free Software Foundation,
19218822Sdim * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20218822Sdim *
21218822Sdim * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22218822Sdim * or visit www.oracle.com if you need additional information or have any
23218822Sdim * questions.
24218822Sdim */
25218822Sdim
26218822Sdimpackage com.sun.tools.javap;
27218822Sdim
28218822Sdimimport com.sun.tools.classfile.AccessFlags;
29218822Sdimimport com.sun.tools.classfile.AnnotationDefault_attribute;
30218822Sdimimport com.sun.tools.classfile.Attribute;
31218822Sdimimport com.sun.tools.classfile.Attributes;
32218822Sdimimport com.sun.tools.classfile.BootstrapMethods_attribute;
33218822Sdimimport com.sun.tools.classfile.CharacterRangeTable_attribute;
34218822Sdimimport com.sun.tools.classfile.CharacterRangeTable_attribute.Entry;
35218822Sdimimport com.sun.tools.classfile.Code_attribute;
36218822Sdimimport com.sun.tools.classfile.CompilationID_attribute;
37218822Sdimimport com.sun.tools.classfile.ConstantPool;
38218822Sdimimport com.sun.tools.classfile.ConstantPoolException;
39218822Sdimimport com.sun.tools.classfile.ConstantValue_attribute;
40218822Sdimimport com.sun.tools.classfile.DefaultAttribute;
41218822Sdimimport com.sun.tools.classfile.Deprecated_attribute;
42218822Sdimimport com.sun.tools.classfile.EnclosingMethod_attribute;
43218822Sdimimport com.sun.tools.classfile.Exceptions_attribute;
44218822Sdimimport com.sun.tools.classfile.InnerClasses_attribute;
45218822Sdimimport com.sun.tools.classfile.InnerClasses_attribute.Info;
46218822Sdimimport com.sun.tools.classfile.LineNumberTable_attribute;
47218822Sdimimport com.sun.tools.classfile.LocalVariableTable_attribute;
48218822Sdimimport com.sun.tools.classfile.LocalVariableTypeTable_attribute;
49218822Sdimimport com.sun.tools.classfile.MethodParameters_attribute;
50218822Sdimimport com.sun.tools.classfile.Module_attribute;
51218822Sdimimport com.sun.tools.classfile.ModuleHashes_attribute;
52218822Sdimimport com.sun.tools.classfile.ModuleMainClass_attribute;
53218822Sdimimport com.sun.tools.classfile.ModulePackages_attribute;
54218822Sdimimport com.sun.tools.classfile.ModuleTarget_attribute;
55218822Sdimimport com.sun.tools.classfile.ModuleVersion_attribute;
56218822Sdimimport com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute;
57218822Sdimimport com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute;
58218822Sdimimport com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute;
59218822Sdimimport com.sun.tools.classfile.RuntimeVisibleAnnotations_attribute;
60218822Sdimimport com.sun.tools.classfile.RuntimeVisibleParameterAnnotations_attribute;
61218822Sdimimport com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute;
62218822Sdimimport com.sun.tools.classfile.Signature_attribute;
63218822Sdimimport com.sun.tools.classfile.SourceDebugExtension_attribute;
64218822Sdimimport com.sun.tools.classfile.SourceFile_attribute;
65218822Sdimimport com.sun.tools.classfile.SourceID_attribute;
66218822Sdimimport com.sun.tools.classfile.StackMapTable_attribute;
67218822Sdimimport com.sun.tools.classfile.StackMap_attribute;
68218822Sdimimport com.sun.tools.classfile.Synthetic_attribute;
69218822Sdim
70218822Sdimimport static com.sun.tools.classfile.AccessFlags.*;
71218822Sdim
72218822Sdimimport com.sun.tools.javac.util.Assert;
73218822Sdimimport com.sun.tools.javac.util.StringUtils;
74218822Sdim
75218822Sdim/*
76218822Sdim *  A writer for writing Attributes as text.
77218822Sdim *
78218822Sdim *  <p><b>This is NOT part of any supported API.
79218822Sdim *  If you write code that depends on this, you do so at your own risk.
80218822Sdim *  This code and its internal interfaces are subject to change or
81218822Sdim *  deletion without notice.</b>
82218822Sdim */
83218822Sdimpublic class AttributeWriter extends BasicWriter
84218822Sdim        implements Attribute.Visitor<Void,Void>
85218822Sdim{
86218822Sdim    public static AttributeWriter instance(Context context) {
87218822Sdim        AttributeWriter instance = context.get(AttributeWriter.class);
88218822Sdim        if (instance == null)
89218822Sdim            instance = new AttributeWriter(context);
90218822Sdim        return instance;
91218822Sdim    }
92218822Sdim
93218822Sdim    protected AttributeWriter(Context context) {
94218822Sdim        super(context);
95218822Sdim        context.put(AttributeWriter.class, this);
96218822Sdim        annotationWriter = AnnotationWriter.instance(context);
97218822Sdim        codeWriter = CodeWriter.instance(context);
98218822Sdim        constantWriter = ConstantWriter.instance(context);
99218822Sdim        options = Options.instance(context);
100218822Sdim    }
101218822Sdim
102218822Sdim    public void write(Object owner, Attribute attr, ConstantPool constant_pool) {
103218822Sdim        if (attr != null) {
104218822Sdim            Assert.checkNonNull(constant_pool);
105218822Sdim            Assert.checkNonNull(owner);
106218822Sdim            this.constant_pool = constant_pool;
107218822Sdim            this.owner = owner;
108218822Sdim            attr.accept(this, null);
109218822Sdim        }
110218822Sdim    }
111218822Sdim
112218822Sdim    public void write(Object owner, Attributes attrs, ConstantPool constant_pool) {
113218822Sdim        if (attrs != null) {
114218822Sdim            Assert.checkNonNull(constant_pool);
115218822Sdim            Assert.checkNonNull(owner);
116218822Sdim            this.constant_pool = constant_pool;
117218822Sdim            this.owner = owner;
118218822Sdim            for (Attribute attr: attrs)
119218822Sdim                attr.accept(this, null);
120218822Sdim        }
121218822Sdim    }
122218822Sdim
123218822Sdim    @Override
124218822Sdim    public Void visitDefault(DefaultAttribute attr, Void ignore) {
125218822Sdim        if (attr.reason != null) {
126218822Sdim            report(attr.reason);
127218822Sdim        }
128218822Sdim        byte[] data = attr.info;
129218822Sdim        int i = 0;
130218822Sdim        int j = 0;
131218822Sdim        print("  ");
132218822Sdim        try {
133218822Sdim            print(attr.getName(constant_pool));
134218822Sdim        } catch (ConstantPoolException e) {
135218822Sdim            report(e);
136218822Sdim            print("attribute name = #" + attr.attribute_name_index);
137218822Sdim        }
138218822Sdim        print(": ");
139218822Sdim        println("length = 0x" + toHex(attr.info.length));
140218822Sdim
141218822Sdim        print("   ");
142218822Sdim
143218822Sdim        while (i < data.length) {
144218822Sdim            print(toHex(data[i], 2));
145218822Sdim
146218822Sdim            j++;
147218822Sdim            if (j == 16) {
148218822Sdim                println();
149218822Sdim                print("   ");
150218822Sdim                j = 0;
151218822Sdim            } else {
152218822Sdim                print(" ");
153218822Sdim            }
154218822Sdim            i++;
155218822Sdim        }
156218822Sdim        println();
157218822Sdim        return null;
158218822Sdim    }
159218822Sdim
160218822Sdim    @Override
161218822Sdim    public Void visitAnnotationDefault(AnnotationDefault_attribute attr, Void ignore) {
162218822Sdim        println("AnnotationDefault:");
163218822Sdim        indent(+1);
164218822Sdim        print("default_value: ");
165218822Sdim        annotationWriter.write(attr.default_value);
166218822Sdim        indent(-1);
167218822Sdim        return null;
168218822Sdim    }
169218822Sdim
170218822Sdim    @Override
171218822Sdim    public Void visitBootstrapMethods(BootstrapMethods_attribute attr, Void p) {
172218822Sdim        println(Attribute.BootstrapMethods + ":");
173218822Sdim        for (int i = 0; i < attr.bootstrap_method_specifiers.length ; i++) {
174218822Sdim            BootstrapMethods_attribute.BootstrapMethodSpecifier bsm = attr.bootstrap_method_specifiers[i];
175218822Sdim            indent(+1);
176218822Sdim            print(i + ": #" + bsm.bootstrap_method_ref + " ");
177218822Sdim            println(constantWriter.stringValue(bsm.bootstrap_method_ref));
178218822Sdim            indent(+1);
179218822Sdim            println("Method arguments:");
180218822Sdim            indent(+1);
181218822Sdim            for (int j = 0; j < bsm.bootstrap_arguments.length; j++) {
182218822Sdim                print("#" + bsm.bootstrap_arguments[j] + " ");
183218822Sdim                println(constantWriter.stringValue(bsm.bootstrap_arguments[j]));
184218822Sdim            }
185218822Sdim            indent(-3);
186218822Sdim        }
187218822Sdim        return null;
188218822Sdim    }
189218822Sdim
190218822Sdim    @Override
191218822Sdim    public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, Void ignore) {
192218822Sdim        println("CharacterRangeTable:");
193218822Sdim        indent(+1);
194218822Sdim        for (Entry e : attr.character_range_table) {
195218822Sdim            print(String.format("    %2d, %2d, %6x, %6x, %4x",
196218822Sdim                    e.start_pc, e.end_pc,
197218822Sdim                    e.character_range_start, e.character_range_end,
198218822Sdim                    e.flags));
199218822Sdim            tab();
200218822Sdim            print(String.format("// %2d, %2d, %4d:%02d, %4d:%02d",
201218822Sdim                    e.start_pc, e.end_pc,
202218822Sdim                    (e.character_range_start >> 10), (e.character_range_start & 0x3ff),
203218822Sdim                    (e.character_range_end >> 10), (e.character_range_end & 0x3ff)));
204218822Sdim            if ((e.flags & CharacterRangeTable_attribute.CRT_STATEMENT) != 0)
205218822Sdim                print(", statement");
206218822Sdim            if ((e.flags & CharacterRangeTable_attribute.CRT_BLOCK) != 0)
207218822Sdim                print(", block");
208218822Sdim            if ((e.flags & CharacterRangeTable_attribute.CRT_ASSIGNMENT) != 0)
209218822Sdim                print(", assignment");
210218822Sdim            if ((e.flags & CharacterRangeTable_attribute.CRT_FLOW_CONTROLLER) != 0)
211218822Sdim                print(", flow-controller");
212218822Sdim            if ((e.flags & CharacterRangeTable_attribute.CRT_FLOW_TARGET) != 0)
213218822Sdim                print(", flow-target");
214218822Sdim            if ((e.flags & CharacterRangeTable_attribute.CRT_INVOKE) != 0)
215218822Sdim                print(", invoke");
216218822Sdim            if ((e.flags & CharacterRangeTable_attribute.CRT_CREATE) != 0)
217218822Sdim                print(", create");
218218822Sdim            if ((e.flags & CharacterRangeTable_attribute.CRT_BRANCH_TRUE) != 0)
219218822Sdim                print(", branch-true");
220218822Sdim            if ((e.flags & CharacterRangeTable_attribute.CRT_BRANCH_FALSE) != 0)
221218822Sdim                print(", branch-false");
222218822Sdim            println();
223218822Sdim        }
224218822Sdim        indent(-1);
225218822Sdim        return null;
226218822Sdim    }
227218822Sdim
228218822Sdim    @Override
229218822Sdim    public Void visitCode(Code_attribute attr, Void ignore) {
230218822Sdim        codeWriter.write(attr, constant_pool);
231218822Sdim        return null;
232218822Sdim    }
233218822Sdim
234218822Sdim    @Override
235218822Sdim    public Void visitCompilationID(CompilationID_attribute attr, Void ignore) {
236218822Sdim        constantWriter.write(attr.compilationID_index);
237218822Sdim        return null;
238218822Sdim    }
239218822Sdim
240218822Sdim    private String getJavaPackage(ModulePackages_attribute attr, int index) {
241218822Sdim        try {
242218822Sdim            return getJavaName(attr.getPackage(index, constant_pool));
243218822Sdim        } catch (ConstantPoolException e) {
244218822Sdim            return report(e);
245218822Sdim        }
246218822Sdim    }
247218822Sdim
248218822Sdim    @Override
249218822Sdim    public Void visitModulePackages(ModulePackages_attribute attr, Void ignore) {
250218822Sdim        println("ModulePackages: ");
251218822Sdim        indent(+1);
252218822Sdim        for (int i = 0; i < attr.packages_count; i++) {
253218822Sdim            print("#" + attr.packages_index[i]);
254218822Sdim            tab();
255218822Sdim            println("// " + getJavaPackage(attr, i));
256218822Sdim        }
257218822Sdim        indent(-1);
258218822Sdim        return null;
259218822Sdim    }
260218822Sdim
261218822Sdim    @Override
262218822Sdim    public Void visitConstantValue(ConstantValue_attribute attr, Void ignore) {
263218822Sdim        print("ConstantValue: ");
264218822Sdim        constantWriter.write(attr.constantvalue_index);
265218822Sdim        println();
266218822Sdim        return null;
267218822Sdim    }
268218822Sdim
269218822Sdim    @Override
270218822Sdim    public Void visitDeprecated(Deprecated_attribute attr, Void ignore) {
271218822Sdim        println("Deprecated: true");
272218822Sdim        return null;
273218822Sdim    }
274218822Sdim
275218822Sdim    @Override
276218822Sdim    public Void visitEnclosingMethod(EnclosingMethod_attribute attr, Void ignore) {
277218822Sdim        print("EnclosingMethod: #" + attr.class_index + ".#" + attr.method_index);
278218822Sdim        tab();
279218822Sdim        print("// " + getJavaClassName(attr));
280218822Sdim        if (attr.method_index != 0)
281218822Sdim            print("." + getMethodName(attr));
282218822Sdim        println();
283218822Sdim        return null;
284218822Sdim    }
285218822Sdim
286218822Sdim    private String getJavaClassName(EnclosingMethod_attribute a) {
287218822Sdim        try {
288218822Sdim            return getJavaName(a.getClassName(constant_pool));
289218822Sdim        } catch (ConstantPoolException e) {
290218822Sdim            return report(e);
291218822Sdim        }
292218822Sdim    }
293218822Sdim
294218822Sdim    private String getMethodName(EnclosingMethod_attribute a) {
295218822Sdim        try {
296218822Sdim            return a.getMethodName(constant_pool);
297218822Sdim        } catch (ConstantPoolException e) {
298218822Sdim            return report(e);
299218822Sdim        }
300218822Sdim    }
301218822Sdim
302218822Sdim    @Override
303218822Sdim    public Void visitExceptions(Exceptions_attribute attr, Void ignore) {
304218822Sdim        println("Exceptions:");
305218822Sdim        indent(+1);
306218822Sdim        print("throws ");
307218822Sdim        for (int i = 0; i < attr.number_of_exceptions; i++) {
308218822Sdim            if (i > 0)
309218822Sdim                print(", ");
310218822Sdim            print(getJavaException(attr, i));
311218822Sdim        }
312218822Sdim        println();
313218822Sdim        indent(-1);
314218822Sdim        return null;
315218822Sdim    }
316218822Sdim
317218822Sdim    private String getJavaException(Exceptions_attribute attr, int index) {
318218822Sdim        try {
319218822Sdim            return getJavaName(attr.getException(index, constant_pool));
320218822Sdim        } catch (ConstantPoolException e) {
321218822Sdim            return report(e);
322218822Sdim        }
323218822Sdim    }
324218822Sdim
325218822Sdim    @Override
326218822Sdim    public Void visitModuleHashes(ModuleHashes_attribute attr, Void ignore) {
327218822Sdim        println("ModuleHashes:");
328218822Sdim        indent(+1);
329218822Sdim        print("algorithm #" + attr.algorithm_index);
330218822Sdim        tab();
331218822Sdim        println("// " + getAlgorithm(attr));
332218822Sdim        for (ModuleHashes_attribute.Entry e : attr.hashes_table) {
333218822Sdim            print("#" + e.module_name_index);
334218822Sdim            tab();
335218822Sdim            println("// " + getModuleName(e));
336218822Sdim            println("hash_length: " + e.hash.length);
337218822Sdim            println("hash: [" + toHex(e.hash) + "]");
338218822Sdim        }
339218822Sdim        indent(-1);
340218822Sdim        return null;
341218822Sdim    }
342218822Sdim
343218822Sdim    private String getAlgorithm(ModuleHashes_attribute attr) {
344218822Sdim        try {
345218822Sdim            return constant_pool.getUTF8Value(attr.algorithm_index);
346218822Sdim        } catch (ConstantPoolException e) {
347218822Sdim            return report(e);
348218822Sdim        }
349218822Sdim    }
350218822Sdim
351218822Sdim    private String getModuleName(ModuleHashes_attribute.Entry entry) {
352218822Sdim        try {
353218822Sdim            return constant_pool.getUTF8Value(entry.module_name_index);
354218822Sdim        } catch (ConstantPoolException e) {
355218822Sdim            return report(e);
356218822Sdim        }
357218822Sdim    }
358218822Sdim
359218822Sdim    @Override
360218822Sdim    public Void visitInnerClasses(InnerClasses_attribute attr, Void ignore) {
361218822Sdim        boolean first = true;
362218822Sdim        for (Info info : attr.classes) {
363218822Sdim            //access
364218822Sdim            AccessFlags access_flags = info.inner_class_access_flags;
365218822Sdim            if (options.checkAccess(access_flags)) {
366218822Sdim                if (first) {
367218822Sdim                    writeInnerClassHeader();
368218822Sdim                    first = false;
369218822Sdim                }
370218822Sdim                for (String name: access_flags.getInnerClassModifiers())
371218822Sdim                    print(name + " ");
372218822Sdim                if (info.inner_name_index != 0) {
373218822Sdim                    print("#" + info.inner_name_index + "= ");
374218822Sdim                }
375218822Sdim                print("#" + info.inner_class_info_index);
376218822Sdim                if (info.outer_class_info_index != 0) {
377218822Sdim                    print(" of #" + info.outer_class_info_index);
378218822Sdim                }
379218822Sdim                print(";");
380218822Sdim                tab();
381218822Sdim                print("// ");
382218822Sdim                if (info.inner_name_index != 0) {
383218822Sdim                    print(getInnerName(constant_pool, info) + "=");
384218822Sdim                }
385218822Sdim                constantWriter.write(info.inner_class_info_index);
386218822Sdim                if (info.outer_class_info_index != 0) {
387218822Sdim                    print(" of ");
388218822Sdim                    constantWriter.write(info.outer_class_info_index);
389218822Sdim                }
390218822Sdim                println();
391218822Sdim            }
392218822Sdim        }
393218822Sdim        if (!first)
394218822Sdim            indent(-1);
395218822Sdim        return null;
396218822Sdim    }
397218822Sdim
398218822Sdim    String getInnerName(ConstantPool constant_pool, InnerClasses_attribute.Info info) {
399218822Sdim        try {
400218822Sdim            return info.getInnerName(constant_pool);
401218822Sdim        } catch (ConstantPoolException e) {
402218822Sdim            return report(e);
40333965Sjdp        }
404218822Sdim    }
405218822Sdim
406218822Sdim    private void writeInnerClassHeader() {
407218822Sdim        println("InnerClasses:");
408218822Sdim        indent(+1);
409218822Sdim    }
41033965Sjdp
411218822Sdim    @Override
412218822Sdim    public Void visitLineNumberTable(LineNumberTable_attribute attr, Void ignore) {
413218822Sdim        println("LineNumberTable:");
414218822Sdim        indent(+1);
415218822Sdim        for (LineNumberTable_attribute.Entry entry: attr.line_number_table) {
416218822Sdim            println("line " + entry.line_number + ": " + entry.start_pc);
417218822Sdim        }
418218822Sdim        indent(-1);
419218822Sdim        return null;
420218822Sdim    }
421218822Sdim
422218822Sdim    @Override
423218822Sdim    public Void visitLocalVariableTable(LocalVariableTable_attribute attr, Void ignore) {
424218822Sdim        println("LocalVariableTable:");
425218822Sdim        indent(+1);
426218822Sdim        println("Start  Length  Slot  Name   Signature");
427218822Sdim        for (LocalVariableTable_attribute.Entry entry : attr.local_variable_table) {
428218822Sdim            println(String.format("%5d %7d %5d %5s   %s",
429218822Sdim                    entry.start_pc, entry.length, entry.index,
430218822Sdim                    constantWriter.stringValue(entry.name_index),
431218822Sdim                    constantWriter.stringValue(entry.descriptor_index)));
432218822Sdim        }
433218822Sdim        indent(-1);
434218822Sdim        return null;
435218822Sdim    }
436218822Sdim
437218822Sdim    @Override
438218822Sdim    public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, Void ignore) {
439218822Sdim        println("LocalVariableTypeTable:");
440218822Sdim        indent(+1);
441218822Sdim        println("Start  Length  Slot  Name   Signature");
442218822Sdim        for (LocalVariableTypeTable_attribute.Entry entry : attr.local_variable_table) {
443218822Sdim            println(String.format("%5d %7d %5d %5s   %s",
444218822Sdim                    entry.start_pc, entry.length, entry.index,
445218822Sdim                    constantWriter.stringValue(entry.name_index),
446218822Sdim                    constantWriter.stringValue(entry.signature_index)));
447218822Sdim        }
448218822Sdim        indent(-1);
449218822Sdim        return null;
450218822Sdim    }
451218822Sdim
452218822Sdim    @Override
453218822Sdim    public Void visitModuleMainClass(ModuleMainClass_attribute attr, Void ignore) {
454218822Sdim        print("ModuleMainClass: #" + attr.main_class_index);
455218822Sdim        tab();
456218822Sdim        print("// " + getJavaClassName(attr));
457218822Sdim        println();
458218822Sdim        return null;
459218822Sdim    }
460218822Sdim
461218822Sdim    private String getJavaClassName(ModuleMainClass_attribute a) {
462218822Sdim        try {
463218822Sdim            return getJavaName(a.getMainClassName(constant_pool));
46433965Sjdp        } catch (ConstantPoolException e) {
465218822Sdim            return report(e);
466218822Sdim        }
46733965Sjdp    }
46833965Sjdp
469218822Sdim    private static final String format = "%-31s%s";
47033965Sjdp
47133965Sjdp    @Override
47233965Sjdp    public Void visitMethodParameters(MethodParameters_attribute attr,
47333965Sjdp                                      Void ignore) {
47433965Sjdp        final String header = String.format(format, "Name", "Flags");
47533965Sjdp        println("MethodParameters:");
47633965Sjdp        indent(+1);
47733965Sjdp        println(header);
47833965Sjdp        for (MethodParameters_attribute.Entry entry :
47933965Sjdp                 attr.method_parameter_table) {
48033965Sjdp            String namestr =
48133965Sjdp                entry.name_index != 0 ?
48233965Sjdp                constantWriter.stringValue(entry.name_index) : "<no name>";
483218822Sdim            String flagstr =
484218822Sdim                (0 != (entry.flags & ACC_FINAL) ? "final " : "") +
485218822Sdim                (0 != (entry.flags & ACC_MANDATED) ? "mandated " : "") +
486218822Sdim                (0 != (entry.flags & ACC_SYNTHETIC) ? "synthetic" : "");
487218822Sdim            println(String.format(format, namestr, flagstr));
488218822Sdim        }
48933965Sjdp        indent(-1);
49033965Sjdp        return null;
49133965Sjdp    }
49233965Sjdp
49333965Sjdp    @Override
49433965Sjdp    public Void visitModule(Module_attribute attr, Void ignore) {
49533965Sjdp        println("Module:");
49633965Sjdp        indent(+1);
49733965Sjdp
49833965Sjdp        print(attr.module_name);
49933965Sjdp        tab();
50033965Sjdp        println("// " + constantWriter.stringValue(attr.module_name));
50133965Sjdp
50233965Sjdp        print(String.format("%x", attr.module_flags));
50333965Sjdp        tab();
50433965Sjdp        print("// ");
50533965Sjdp        if ((attr.module_flags & Module_attribute.ACC_OPEN) != 0)
50633965Sjdp            print(" ACC_OPEN");
50733965Sjdp        if ((attr.module_flags & Module_attribute.ACC_MANDATED) != 0)
50833965Sjdp            print(" ACC_MANDATED");
50933965Sjdp        if ((attr.module_flags & Module_attribute.ACC_SYNTHETIC) != 0)
51033965Sjdp            print(" ACC_SYNTHETIC");
51133965Sjdp        println();
512218822Sdim
51333965Sjdp        printRequiresTable(attr);
51433965Sjdp        printExportsTable(attr);
51533965Sjdp        printOpensTable(attr);
516218822Sdim        printUsesTable(attr);
51733965Sjdp        printProvidesTable(attr);
51833965Sjdp        indent(-1);
51933965Sjdp        return null;
52033965Sjdp    }
521218822Sdim
52233965Sjdp    protected void printRequiresTable(Module_attribute attr) {
52333965Sjdp        Module_attribute.RequiresEntry[] entries = attr.requires;
524218822Sdim        print(entries.length);
52533965Sjdp        tab();
526218822Sdim        println("// " + "requires");
52733965Sjdp        indent(+1);
52833965Sjdp        for (Module_attribute.RequiresEntry e: entries) {
52933965Sjdp            print("#" + e.requires_index + "," + String.format("%x", e.requires_flags));
53033965Sjdp            tab();
53133965Sjdp            print("// " + constantWriter.stringValue(e.requires_index));
53233965Sjdp            if ((e.requires_flags & Module_attribute.ACC_TRANSITIVE) != 0)
533218822Sdim                print(" ACC_TRANSITIVE");
53433965Sjdp            if ((e.requires_flags & Module_attribute.ACC_STATIC_PHASE) != 0)
535218822Sdim                print(" ACC_STATIC_PHASE");
536218822Sdim            if ((e.requires_flags & Module_attribute.ACC_SYNTHETIC) != 0)
537218822Sdim                print(" ACC_SYNTHETIC");
53833965Sjdp            if ((e.requires_flags & Module_attribute.ACC_MANDATED) != 0)
53933965Sjdp                print(" ACC_MANDATED");
54033965Sjdp            println();
54133965Sjdp        }
542218822Sdim        indent(-1);
54333965Sjdp    }
54433965Sjdp
545218822Sdim    protected void printExportsTable(Module_attribute attr) {
54633965Sjdp        Module_attribute.ExportsEntry[] entries = attr.exports;
547218822Sdim        print(entries.length);
548218822Sdim        tab();
549218822Sdim        println("// exports");
550218822Sdim        indent(+1);
551218822Sdim        for (Module_attribute.ExportsEntry e: entries) {
55233965Sjdp            printExportOpenEntry(e.exports_index, e.exports_flags, e.exports_to_index);
55333965Sjdp        }
554218822Sdim        indent(-1);
55533965Sjdp    }
556218822Sdim
557218822Sdim    protected void printOpensTable(Module_attribute attr) {
558218822Sdim        Module_attribute.OpensEntry[] entries = attr.opens;
559218822Sdim        print(entries.length);
560218822Sdim        tab();
561218822Sdim        println("// opens");
56233965Sjdp        indent(+1);
56333965Sjdp        for (Module_attribute.OpensEntry e: entries) {
564218822Sdim            printExportOpenEntry(e.opens_index, e.opens_flags, e.opens_to_index);
56533965Sjdp        }
56633965Sjdp        indent(-1);
56733965Sjdp    }
56833965Sjdp
56933965Sjdp    protected void printExportOpenEntry(int index, int flags, int[] to_index) {
57033965Sjdp        print("#" + index + "," + String.format("%x", flags));
57133965Sjdp        tab();
57233965Sjdp        print("// ");
573218822Sdim        print(constantWriter.stringValue(index));
57433965Sjdp        if ((flags & Module_attribute.ACC_MANDATED) != 0)
57533965Sjdp            print(" ACC_MANDATED");
57633965Sjdp        if ((flags & Module_attribute.ACC_SYNTHETIC) != 0)
57733965Sjdp            print(" ACC_SYNTHETIC");
57833965Sjdp        if (to_index.length == 0) {
579218822Sdim            println();
580218822Sdim        } else {
581218822Sdim            println(" to ... " + to_index.length);
582218822Sdim            indent(+1);
583218822Sdim            for (int to: to_index) {
584218822Sdim                print("#" + to);
58533965Sjdp                tab();
58633965Sjdp                println("// ... to " + constantWriter.stringValue(to));
587218822Sdim            }
58833965Sjdp            indent(-1);
589218822Sdim        }
59033965Sjdp    }
59133965Sjdp
59233965Sjdp    protected void printUsesTable(Module_attribute attr) {
59333965Sjdp        int[] entries = attr.uses_index;
59433965Sjdp        print(entries.length);
59533965Sjdp        tab();
596218822Sdim        println("// " + "uses");
59733965Sjdp        indent(+1);
59833965Sjdp        for (int e: entries) {
59933965Sjdp            print("#" + e);
60033965Sjdp            tab();
601218822Sdim            println("// " + constantWriter.stringValue(e));
60233965Sjdp        }
60333965Sjdp        indent(-1);
60433965Sjdp    }
60533965Sjdp
606218822Sdim    protected void printProvidesTable(Module_attribute attr) {
60733965Sjdp        Module_attribute.ProvidesEntry[] entries = attr.provides;
60833965Sjdp        print(entries.length);
60933965Sjdp        tab();
61033965Sjdp        println("// " + "provides");
61133965Sjdp        indent(+1);
61233965Sjdp        for (Module_attribute.ProvidesEntry e: entries) {
613218822Sdim            print("#" + e.provides_index);
61433965Sjdp            tab();
61533965Sjdp            print("// ");
61633965Sjdp            print(constantWriter.stringValue(e.provides_index));
61733965Sjdp            println(" with ... " + e.with_count);
61833965Sjdp            indent(+1);
61933965Sjdp            for (int with : e.with_index) {
62033965Sjdp                print("#" + with);
62133965Sjdp                tab();
622218822Sdim                println("// ... with " + constantWriter.stringValue(with));
62333965Sjdp            }
62433965Sjdp            indent(-1);
62533965Sjdp        }
62633965Sjdp        indent(-1);
627218822Sdim    }
62833965Sjdp
62933965Sjdp    @Override
63033965Sjdp    public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, Void ignore) {
63133965Sjdp        println("RuntimeVisibleAnnotations:");
63233965Sjdp        indent(+1);
63333965Sjdp        for (int i = 0; i < attr.annotations.length; i++) {
634218822Sdim            print(i + ": ");
63533965Sjdp            annotationWriter.write(attr.annotations[i]);
63633965Sjdp            println();
63733965Sjdp        }
63833965Sjdp        indent(-1);
63933965Sjdp        return null;
64033965Sjdp    }
64133965Sjdp
64233965Sjdp    @Override
64333965Sjdp    public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, Void ignore) {
64433965Sjdp        println("RuntimeInvisibleAnnotations:");
64533965Sjdp        indent(+1);
64633965Sjdp        for (int i = 0; i < attr.annotations.length; i++) {
64733965Sjdp            print(i + ": ");
648218822Sdim            annotationWriter.write(attr.annotations[i]);
64933965Sjdp            println();
65033965Sjdp        }
65133965Sjdp        indent(-1);
65233965Sjdp        return null;
653218822Sdim    }
65433965Sjdp
65533965Sjdp    @Override
65633965Sjdp    public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, Void ignore) {
65733965Sjdp        println("RuntimeVisibleTypeAnnotations:");
65833965Sjdp        indent(+1);
65933965Sjdp        for (int i = 0; i < attr.annotations.length; i++) {
660218822Sdim            print(i + ": ");
66133965Sjdp            annotationWriter.write(attr.annotations[i]);
66233965Sjdp            println();
66333965Sjdp        }
66433965Sjdp        indent(-1);
66533965Sjdp        return null;
66633965Sjdp    }
667218822Sdim
66833965Sjdp    @Override
66933965Sjdp    public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, Void ignore) {
67033965Sjdp        println("RuntimeInvisibleTypeAnnotations:");
67133965Sjdp        indent(+1);
67233965Sjdp        for (int i = 0; i < attr.annotations.length; i++) {
67333965Sjdp            print(i + ": ");
67433965Sjdp            annotationWriter.write(attr.annotations[i]);
67533965Sjdp            println();
67633965Sjdp        }
67733965Sjdp        indent(-1);
67833965Sjdp        return null;
67933965Sjdp    }
68033965Sjdp
68133965Sjdp    @Override
68233965Sjdp    public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, Void ignore) {
68333965Sjdp        println("RuntimeVisibleParameterAnnotations:");
684218822Sdim        indent(+1);
68533965Sjdp        for (int param = 0; param < attr.parameter_annotations.length; param++) {
68633965Sjdp            println("parameter " + param + ": ");
68733965Sjdp            indent(+1);
68833965Sjdp            for (int i = 0; i < attr.parameter_annotations[param].length; i++) {
68933965Sjdp                print(i + ": ");
69033965Sjdp                annotationWriter.write(attr.parameter_annotations[param][i]);
69133965Sjdp                println();
69233965Sjdp            }
69333965Sjdp            indent(-1);
694218822Sdim        }
69533965Sjdp        indent(-1);
69633965Sjdp        return null;
69733965Sjdp    }
69833965Sjdp
69933965Sjdp    @Override
70033965Sjdp    public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, Void ignore) {
70133965Sjdp        println("RuntimeInvisibleParameterAnnotations:");
70233965Sjdp        indent(+1);
70333965Sjdp        for (int param = 0; param < attr.parameter_annotations.length; param++) {
70433965Sjdp            println(param + ": ");
705218822Sdim            indent(+1);
70633965Sjdp            for (int i = 0; i < attr.parameter_annotations[param].length; i++) {
70733965Sjdp                print(i + ": ");
70833965Sjdp                annotationWriter.write(attr.parameter_annotations[param][i]);
70933965Sjdp                println();
710218822Sdim            }
71133965Sjdp            indent(-1);
71233965Sjdp        }
71333965Sjdp        indent(-1);
71433965Sjdp        return null;
715218822Sdim    }
71633965Sjdp
71733965Sjdp    @Override
71833965Sjdp    public Void visitSignature(Signature_attribute attr, Void ignore) {
71933965Sjdp        print("Signature: #" + attr.signature_index);
72033965Sjdp        tab();
72133965Sjdp        println("// " + getSignature(attr));
722218822Sdim        return null;
72333965Sjdp    }
72433965Sjdp
725218822Sdim    String getSignature(Signature_attribute info) {
72633965Sjdp        try {
727218822Sdim            return info.getSignature(constant_pool);
72833965Sjdp        } catch (ConstantPoolException e) {
72933965Sjdp            return report(e);
73033965Sjdp        }
73133965Sjdp    }
732218822Sdim
733218822Sdim    @Override
73433965Sjdp    public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, Void ignore) {
73533965Sjdp        println("SourceDebugExtension:");
736218822Sdim        indent(+1);
73733965Sjdp        for (String s: attr.getValue().split("[\r\n]+")) {
738218822Sdim            println(s);
739218822Sdim        }
740218822Sdim        indent(-1);
74133965Sjdp        return null;
742218822Sdim    }
743218822Sdim
74433965Sjdp    @Override
74533965Sjdp    public Void visitSourceFile(SourceFile_attribute attr, Void ignore) {
746218822Sdim        println("SourceFile: \"" + getSourceFile(attr) + "\"");
74733965Sjdp        return null;
74833965Sjdp    }
749218822Sdim
75033965Sjdp    private String getSourceFile(SourceFile_attribute attr) {
751218822Sdim        try {
752218822Sdim            return attr.getSourceFile(constant_pool);
753218822Sdim        } catch (ConstantPoolException e) {
754218822Sdim            return report(e);
755218822Sdim        }
75633965Sjdp    }
75733965Sjdp
75833965Sjdp    @Override
75933965Sjdp    public Void visitSourceID(SourceID_attribute attr, Void ignore) {
76033965Sjdp        constantWriter.write(attr.sourceID_index);
76133965Sjdp        return null;
76233965Sjdp    }
76333965Sjdp
76433965Sjdp    @Override
76533965Sjdp    public Void visitStackMap(StackMap_attribute attr, Void ignore) {
766218822Sdim        println("StackMap: number_of_entries = " + attr.number_of_entries);
76733965Sjdp        indent(+1);
76833965Sjdp        StackMapTableWriter w = new StackMapTableWriter();
76933965Sjdp        for (StackMapTable_attribute.stack_map_frame entry : attr.entries) {
77033965Sjdp            w.write(entry);
77133965Sjdp        }
77233965Sjdp        indent(-1);
773218822Sdim        return null;
77433965Sjdp    }
775218822Sdim
776218822Sdim    @Override
777218822Sdim    public Void visitStackMapTable(StackMapTable_attribute attr, Void ignore) {
77833965Sjdp        println("StackMapTable: number_of_entries = " + attr.number_of_entries);
77933965Sjdp        indent(+1);
780218822Sdim        StackMapTableWriter w = new StackMapTableWriter();
781218822Sdim        for (StackMapTable_attribute.stack_map_frame entry : attr.entries) {
782218822Sdim            w.write(entry);
783218822Sdim        }
784218822Sdim        indent(-1);
785218822Sdim        return null;
786218822Sdim    }
787218822Sdim
788218822Sdim    class StackMapTableWriter // also handles CLDC StackMap attributes
789218822Sdim            implements StackMapTable_attribute.stack_map_frame.Visitor<Void,Void> {
79033965Sjdp        public void write(StackMapTable_attribute.stack_map_frame frame) {
791218822Sdim            frame.accept(this, null);
792218822Sdim        }
793218822Sdim
794218822Sdim        @Override
795218822Sdim        public Void visit_same_frame(StackMapTable_attribute.same_frame frame, Void p) {
79633965Sjdp            printHeader(frame, "/* same */");
79733965Sjdp            return null;
79833965Sjdp        }
79933965Sjdp
80033965Sjdp        @Override
80133965Sjdp        public Void visit_same_locals_1_stack_item_frame(StackMapTable_attribute.same_locals_1_stack_item_frame frame, Void p) {
802218822Sdim            printHeader(frame, "/* same_locals_1_stack_item */");
803218822Sdim            indent(+1);
804218822Sdim            printMap("stack", frame.stack);
80533965Sjdp            indent(-1);
80633965Sjdp            return null;
807218822Sdim        }
808218822Sdim
809218822Sdim        @Override
810218822Sdim        public Void visit_same_locals_1_stack_item_frame_extended(StackMapTable_attribute.same_locals_1_stack_item_frame_extended frame, Void p) {
811218822Sdim            printHeader(frame, "/* same_locals_1_stack_item_frame_extended */");
812218822Sdim            indent(+1);
813218822Sdim            println("offset_delta = " + frame.offset_delta);
814218822Sdim            printMap("stack", frame.stack);
815218822Sdim            indent(-1);
816218822Sdim            return null;
81733965Sjdp        }
818218822Sdim
819218822Sdim        @Override
820218822Sdim        public Void visit_chop_frame(StackMapTable_attribute.chop_frame frame, Void p) {
82133965Sjdp            printHeader(frame, "/* chop */");
822218822Sdim            indent(+1);
823218822Sdim            println("offset_delta = " + frame.offset_delta);
824218822Sdim            indent(-1);
825218822Sdim            return null;
826218822Sdim        }
82733965Sjdp
82833965Sjdp        @Override
82933965Sjdp        public Void visit_same_frame_extended(StackMapTable_attribute.same_frame_extended frame, Void p) {
830218822Sdim            printHeader(frame, "/* same_frame_extended */");
831218822Sdim            indent(+1);
832218822Sdim            println("offset_delta = " + frame.offset_delta);
833218822Sdim            indent(-1);
834218822Sdim            return null;
835218822Sdim        }
83633965Sjdp
837218822Sdim        @Override
838218822Sdim        public Void visit_append_frame(StackMapTable_attribute.append_frame frame, Void p) {
839218822Sdim            printHeader(frame, "/* append */");
840218822Sdim            indent(+1);
841218822Sdim            println("offset_delta = " + frame.offset_delta);
842218822Sdim            printMap("locals", frame.locals);
843218822Sdim            indent(-1);
844218822Sdim            return null;
845218822Sdim        }
846218822Sdim
84733965Sjdp        @Override
848218822Sdim        public Void visit_full_frame(StackMapTable_attribute.full_frame frame, Void p) {
849218822Sdim            if (frame instanceof StackMap_attribute.stack_map_frame) {
85033965Sjdp                printHeader(frame, "offset = " + frame.offset_delta);
851218822Sdim                indent(+1);
852218822Sdim            } else {
853218822Sdim                printHeader(frame, "/* full_frame */");
85433965Sjdp                indent(+1);
85533965Sjdp                println("offset_delta = " + frame.offset_delta);
85633965Sjdp            }
85733965Sjdp            printMap("locals", frame.locals);
858218822Sdim            printMap("stack", frame.stack);
859218822Sdim            indent(-1);
860218822Sdim            return null;
861218822Sdim        }
862218822Sdim
863218822Sdim        void printHeader(StackMapTable_attribute.stack_map_frame frame, String extra) {
864218822Sdim            print("frame_type = " + frame.frame_type + " ");
865218822Sdim            println(extra);
866218822Sdim        }
867218822Sdim
868218822Sdim        void printMap(String name, StackMapTable_attribute.verification_type_info[] map) {
869218822Sdim            print(name + " = [");
87033965Sjdp            for (int i = 0; i < map.length; i++) {
87133965Sjdp                StackMapTable_attribute.verification_type_info info = map[i];
87233965Sjdp                int tag = info.tag;
87333965Sjdp                switch (tag) {
87433965Sjdp                    case StackMapTable_attribute.verification_type_info.ITEM_Object:
87533965Sjdp                        print(" ");
87633965Sjdp                        constantWriter.write(((StackMapTable_attribute.Object_variable_info) info).cpool_index);
87733965Sjdp                        break;
87833965Sjdp                    case StackMapTable_attribute.verification_type_info.ITEM_Uninitialized:
879218822Sdim                        print(" " + mapTypeName(tag));
880218822Sdim                        print(" " + ((StackMapTable_attribute.Uninitialized_variable_info) info).offset);
88133965Sjdp                        break;
882218822Sdim                    default:
883218822Sdim                        print(" " + mapTypeName(tag));
88433965Sjdp                }
88533965Sjdp                print(i == (map.length - 1) ? " " : ",");
886218822Sdim            }
887218822Sdim            println("]");
888218822Sdim        }
889218822Sdim
890218822Sdim        String mapTypeName(int tag) {
891218822Sdim            switch (tag) {
892218822Sdim            case StackMapTable_attribute.verification_type_info.ITEM_Top:
893218822Sdim                return "top";
894218822Sdim
895218822Sdim            case StackMapTable_attribute.verification_type_info.ITEM_Integer:
896218822Sdim                return "int";
897218822Sdim
898218822Sdim            case StackMapTable_attribute.verification_type_info.ITEM_Float:
899218822Sdim                return "float";
900218822Sdim
901218822Sdim            case StackMapTable_attribute.verification_type_info.ITEM_Long:
902218822Sdim                return "long";
903218822Sdim
904218822Sdim            case StackMapTable_attribute.verification_type_info.ITEM_Double:
905218822Sdim                return "double";
906218822Sdim
907218822Sdim            case StackMapTable_attribute.verification_type_info.ITEM_Null:
908218822Sdim                return "null";
909218822Sdim
910218822Sdim            case StackMapTable_attribute.verification_type_info.ITEM_UninitializedThis:
911218822Sdim                return "this";
912218822Sdim
913218822Sdim            case StackMapTable_attribute.verification_type_info.ITEM_Object:
914218822Sdim                return "CP";
915218822Sdim
916218822Sdim            case StackMapTable_attribute.verification_type_info.ITEM_Uninitialized:
917218822Sdim                return "uninitialized";
918218822Sdim
919218822Sdim            default:
920218822Sdim                report("unrecognized verification_type_info tag: " + tag);
921218822Sdim                return "[tag:" + tag + "]";
92233965Sjdp            }
923218822Sdim        }
924218822Sdim    }
925218822Sdim
926218822Sdim    @Override
927218822Sdim    public Void visitSynthetic(Synthetic_attribute attr, Void ignore) {
928218822Sdim        println("Synthetic: true");
929218822Sdim        return null;
930218822Sdim    }
931218822Sdim
932218822Sdim    @Override
933218822Sdim    public Void visitModuleTarget(ModuleTarget_attribute attr, Void ignore) {
934218822Sdim        println("ModuleTarget:");
935218822Sdim        indent(+1);
936218822Sdim        print("os_name: #" + attr.os_name_index);
937218822Sdim        if (attr.os_name_index != 0) {
938218822Sdim            tab();
939218822Sdim            print("// " + getOSName(attr));
940218822Sdim        }
941218822Sdim        println();
942218822Sdim        print("os_arch: #" + attr.os_arch_index);
943218822Sdim        if (attr.os_arch_index != 0) {
944218822Sdim            tab();
945218822Sdim            print("// " + getOSArch(attr));
946218822Sdim        }
947218822Sdim        println();
948218822Sdim        print("os_version: #" + attr.os_version_index);
949218822Sdim        if (attr.os_version_index != 0) {
950218822Sdim            tab();
951218822Sdim            print("// " + getOSVersion(attr));
952218822Sdim        }
953218822Sdim        println();
954218822Sdim        indent(-1);
955218822Sdim        return null;
956218822Sdim    }
957218822Sdim
958218822Sdim    private String getOSName(ModuleTarget_attribute attr) {
959218822Sdim        try {
960218822Sdim            return constant_pool.getUTF8Value(attr.os_name_index);
961218822Sdim        } catch (ConstantPoolException e) {
962218822Sdim            return report(e);
963218822Sdim        }
964218822Sdim    }
965218822Sdim
966218822Sdim    private String getOSArch(ModuleTarget_attribute attr) {
967218822Sdim        try {
968218822Sdim            return constant_pool.getUTF8Value(attr.os_arch_index);
969218822Sdim        } catch (ConstantPoolException e) {
970218822Sdim            return report(e);
971218822Sdim        }
972218822Sdim    }
973218822Sdim
974218822Sdim    private String getOSVersion(ModuleTarget_attribute attr) {
975218822Sdim        try {
976218822Sdim            return constant_pool.getUTF8Value(attr.os_version_index);
977218822Sdim        } catch (ConstantPoolException e) {
978218822Sdim            return report(e);
979218822Sdim        }
980218822Sdim    }
981218822Sdim
982218822Sdim    @Override
983218822Sdim    public Void visitModuleVersion(ModuleVersion_attribute attr, Void ignore) {
984218822Sdim        print("ModuleVersion: #" + attr.version_index);
985218822Sdim        indent(+1);
986218822Sdim        tab();
987218822Sdim        println("// " + getVersion(attr));
988218822Sdim        indent(-1);
989218822Sdim        return null;
990218822Sdim    }
991218822Sdim
992218822Sdim    private String getVersion(ModuleVersion_attribute attr) {
993218822Sdim        try {
994218822Sdim            return constant_pool.getUTF8Value(attr.version_index);
995218822Sdim        } catch (ConstantPoolException e) {
996218822Sdim            return report(e);
997218822Sdim        }
998218822Sdim    }
999218822Sdim
1000218822Sdim    static String getJavaName(String name) {
1001218822Sdim        return name.replace('/', '.');
1002218822Sdim    }
1003218822Sdim
1004218822Sdim    String toHex(byte b, int w) {
1005218822Sdim        return toHex(b & 0xff, w);
1006218822Sdim    }
1007218822Sdim
1008218822Sdim    static String toHex(int i) {
1009218822Sdim        return StringUtils.toUpperCase(Integer.toString(i, 16));
1010218822Sdim    }
1011218822Sdim
1012218822Sdim    static String toHex(int i, int w) {
1013218822Sdim        String s = StringUtils.toUpperCase(Integer.toHexString(i));
1014218822Sdim        while (s.length() < w)
1015218822Sdim            s = "0" + s;
1016218822Sdim        return StringUtils.toUpperCase(s);
1017218822Sdim    }
1018218822Sdim
1019218822Sdim    static String toHex(byte[] ba) {
1020218822Sdim        StringBuilder sb = new StringBuilder(ba.length);
1021218822Sdim        for (byte b: ba) {
1022218822Sdim            sb.append(String.format("%02x", b & 0xff));
1023218822Sdim        }
1024218822Sdim        return sb.toString();
1025218822Sdim    }
1026218822Sdim
1027218822Sdim    private final AnnotationWriter annotationWriter;
1028218822Sdim    private final CodeWriter codeWriter;
1029218822Sdim    private final ConstantWriter constantWriter;
1030218822Sdim    private final Options options;
1031218822Sdim
1032218822Sdim    private ConstantPool constant_pool;
1033218822Sdim    private Object owner;
1034218822Sdim}
1035218822Sdim