• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Javassist, a Java-bytecode translator toolkit.
3  * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
4  *
5  * The contents of this file are subject to the Mozilla Public License Version
6  * 1.1 (the "License"); you may not use this file except in compliance with
7  * the License.  Alternatively, the contents of this file may be used under
8  * the terms of the GNU Lesser General Public License Version 2.1 or later,
9  * or the Apache License Version 2.0.
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  */
16 
17 package javassist.bytecode;
18 
19 import java.io.PrintWriter;
20 import java.util.List;
21 
22 import javassist.Modifier;
23 
24 /**
25  * A utility class for priting the contents of a class file.
26  * It prints a constant pool table, fields, and methods in a
27  * human readable representation.
28  */
29 public class ClassFilePrinter {
30     /**
31      * Prints the contents of a class file to the standard output stream.
32      */
print(ClassFile cf)33     public static void print(ClassFile cf) {
34         print(cf, new PrintWriter(System.out, true));
35     }
36 
37     /**
38      * Prints the contents of a class file.
39      */
print(ClassFile cf, PrintWriter out)40     public static void print(ClassFile cf, PrintWriter out) {
41         /* 0x0020 (SYNCHRONIZED) means ACC_SUPER if the modifiers
42          * are of a class.
43          */
44         int mod
45             = AccessFlag.toModifier(cf.getAccessFlags()
46                                     & ~AccessFlag.SYNCHRONIZED);
47         out.println("major: " + cf.major + ", minor: " + cf.minor
48                     + " modifiers: " + Integer.toHexString(cf.getAccessFlags()));
49         out.println(Modifier.toString(mod) + " class "
50                     + cf.getName() + " extends " + cf.getSuperclass());
51 
52         String[] infs = cf.getInterfaces();
53         if (infs != null && infs.length > 0) {
54             out.print("    implements ");
55             out.print(infs[0]);
56             for (int i = 1; i < infs.length; ++i)
57                 out.print(", " + infs[i]);
58 
59             out.println();
60         }
61 
62         out.println();
63         List<FieldInfo> fields = cf.getFields();
64         for (FieldInfo finfo:fields) {
65             int acc = finfo.getAccessFlags();
66             out.println(Modifier.toString(AccessFlag.toModifier(acc))
67                         + " " + finfo.getName() + "\t"
68                         + finfo.getDescriptor());
69             printAttributes(finfo.getAttributes(), out, 'f');
70         }
71 
72         out.println();
73         List<MethodInfo> methods = cf.getMethods();
74         for (MethodInfo minfo:methods) {
75             int acc = minfo.getAccessFlags();
76             out.println(Modifier.toString(AccessFlag.toModifier(acc))
77                         + " " + minfo.getName() + "\t"
78                         + minfo.getDescriptor());
79             printAttributes(minfo.getAttributes(), out, 'm');
80             out.println();
81         }
82 
83         out.println();
84         printAttributes(cf.getAttributes(), out, 'c');
85     }
86 
printAttributes(List<AttributeInfo> list, PrintWriter out, char kind)87     static void printAttributes(List<AttributeInfo> list, PrintWriter out, char kind) {
88         if (list == null)
89             return;
90 
91         for (AttributeInfo ai:list) {
92             if (ai instanceof CodeAttribute) {
93                 CodeAttribute ca = (CodeAttribute)ai;
94                 out.println("attribute: " + ai.getName() + ": "
95                             + ai.getClass().getName());
96                 out.println("max stack " + ca.getMaxStack()
97                             + ", max locals " + ca.getMaxLocals()
98                             + ", " + ca.getExceptionTable().size()
99                             + " catch blocks");
100                 out.println("<code attribute begin>");
101                 printAttributes(ca.getAttributes(), out, kind);
102                 out.println("<code attribute end>");
103             }
104             else if (ai instanceof AnnotationsAttribute) {
105                 out.println("annnotation: " + ai.toString());
106             }
107             else if (ai instanceof ParameterAnnotationsAttribute) {
108                 out.println("parameter annnotations: " + ai.toString());
109             }
110             else if (ai instanceof StackMapTable) {
111                 out.println("<stack map table begin>");
112                 StackMapTable.Printer.print((StackMapTable)ai, out);
113                 out.println("<stack map table end>");
114             }
115             else if (ai instanceof StackMap) {
116                 out.println("<stack map begin>");
117                 ((StackMap)ai).print(out);
118                 out.println("<stack map end>");
119             }
120             else if (ai instanceof SignatureAttribute) {
121                 SignatureAttribute sa = (SignatureAttribute)ai;
122                 String sig = sa.getSignature();
123                 out.println("signature: " + sig);
124                 try {
125                     String s;
126                     if (kind == 'c')
127                         s = SignatureAttribute.toClassSignature(sig).toString();
128                     else if (kind == 'm')
129                         s = SignatureAttribute.toMethodSignature(sig).toString();
130                     else
131                         s = SignatureAttribute.toFieldSignature(sig).toString();
132 
133                     out.println("           " + s);
134                 }
135                 catch (BadBytecode e) {
136                     out.println("           syntax error");
137                 }
138             }
139             else
140                 out.println("attribute: " + ai.getName()
141                             + " (" + ai.get().length + " byte): "
142                             + ai.getClass().getName());
143         }
144     }
145 }
146