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