/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later,
* or the Apache License Version 2.0.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package javassist.bytecode;
import java.io.
PrintWriter;
import java.util.
List;
import javassist.
Modifier;
/**
* A utility class for priting the contents of a class file.
* It prints a constant pool table, fields, and methods in a
* human readable representation.
*/
public class
ClassFilePrinter {
/**
* Prints the contents of a class file to the standard output stream.
*/
public static void
print(
ClassFile cf) {
print(
cf, new
PrintWriter(
System.
out, true));
}
/**
* Prints the contents of a class file.
*/
public static void
print(
ClassFile cf,
PrintWriter out) {
/* 0x0020 (SYNCHRONIZED) means ACC_SUPER if the modifiers
* are of a class.
*/
int
mod
=
AccessFlag.
toModifier(
cf.
getAccessFlags()
& ~
AccessFlag.
SYNCHRONIZED);
out.
println("major: " +
cf.
major + ", minor: " +
cf.
minor
+ " modifiers: " +
Integer.
toHexString(
cf.
getAccessFlags()));
out.
println(
Modifier.
toString(
mod) + " class "
+
cf.
getName() + " extends " +
cf.
getSuperclass());
String[]
infs =
cf.
getInterfaces();
if (
infs != null &&
infs.length > 0) {
out.
print(" implements ");
out.
print(
infs[0]);
for (int
i = 1;
i <
infs.length; ++
i)
out.
print(", " +
infs[
i]);
out.
println();
}
out.
println();
List<
FieldInfo>
fields =
cf.
getFields();
for (
FieldInfo finfo:
fields) {
int
acc =
finfo.
getAccessFlags();
out.
println(
Modifier.
toString(
AccessFlag.
toModifier(
acc))
+ " " +
finfo.
getName() + "\t"
+
finfo.
getDescriptor());
printAttributes(
finfo.
getAttributes(),
out, 'f');
}
out.
println();
List<
MethodInfo>
methods =
cf.
getMethods();
for (
MethodInfo minfo:
methods) {
int
acc =
minfo.
getAccessFlags();
out.
println(
Modifier.
toString(
AccessFlag.
toModifier(
acc))
+ " " +
minfo.
getName() + "\t"
+
minfo.
getDescriptor());
printAttributes(
minfo.
getAttributes(),
out, 'm');
out.
println();
}
out.
println();
printAttributes(
cf.
getAttributes(),
out, 'c');
}
static void
printAttributes(
List<
AttributeInfo>
list,
PrintWriter out, char
kind) {
if (
list == null)
return;
for (
AttributeInfo ai:
list) {
if (
ai instanceof
CodeAttribute) {
CodeAttribute ca = (
CodeAttribute)
ai;
out.
println("attribute: " +
ai.
getName() + ": "
+
ai.
getClass().
getName());
out.
println("max stack " +
ca.
getMaxStack()
+ ", max locals " +
ca.
getMaxLocals()
+ ", " +
ca.
getExceptionTable().
size()
+ " catch blocks");
out.
println("<code attribute begin>");
printAttributes(
ca.
getAttributes(),
out,
kind);
out.
println("<code attribute end>");
}
else if (
ai instanceof
AnnotationsAttribute) {
out.
println("annnotation: " +
ai.
toString());
}
else if (
ai instanceof
ParameterAnnotationsAttribute) {
out.
println("parameter annnotations: " +
ai.
toString());
}
else if (
ai instanceof
StackMapTable) {
out.
println("<stack map table begin>");
StackMapTable.
Printer.
print((
StackMapTable)
ai,
out);
out.
println("<stack map table end>");
}
else if (
ai instanceof
StackMap) {
out.
println("<stack map begin>");
((
StackMap)
ai).
print(
out);
out.
println("<stack map end>");
}
else if (
ai instanceof
SignatureAttribute) {
SignatureAttribute sa = (
SignatureAttribute)
ai;
String sig =
sa.
getSignature();
out.
println("signature: " +
sig);
try {
String s;
if (
kind == 'c')
s =
SignatureAttribute.
toClassSignature(
sig).
toString();
else if (
kind == 'm')
s =
SignatureAttribute.
toMethodSignature(
sig).
toString();
else
s =
SignatureAttribute.
toFieldSignature(
sig).
toString();
out.
println(" " +
s);
}
catch (
BadBytecode e) {
out.
println(" syntax error");
}
}
else
out.
println("attribute: " +
ai.
getName()
+ " (" +
ai.
get().length + " byte): "
+
ai.
getClass().
getName());
}
}
}