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