Home | History | Annotate | Download | only in bytecode
      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