Home | History | Annotate | Download | only in visitor
      1 /*
      2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
      3  *             of Java bytecode.
      4  *
      5  * Copyright (c) 2002-2009 Eric Lafortune (eric (at) graphics.cornell.edu)
      6  *
      7  * This program is free software; you can redistribute it and/or modify it
      8  * under the terms of the GNU General Public License as published by the Free
      9  * Software Foundation; either version 2 of the License, or (at your option)
     10  * any later version.
     11  *
     12  * This program is distributed in the hope that it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
     15  * more details.
     16  *
     17  * You should have received a copy of the GNU General Public License along
     18  * with this program; if not, write to the Free Software Foundation, Inc.,
     19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20  */
     21 package proguard.classfile.visitor;
     22 
     23 import proguard.classfile.*;
     24 import proguard.classfile.attribute.*;
     25 import proguard.classfile.attribute.annotation.*;
     26 import proguard.classfile.attribute.annotation.visitor.*;
     27 import proguard.classfile.attribute.preverification.*;
     28 import proguard.classfile.attribute.preverification.visitor.*;
     29 import proguard.classfile.attribute.visitor.*;
     30 import proguard.classfile.constant.*;
     31 import proguard.classfile.constant.visitor.ConstantVisitor;
     32 import proguard.classfile.instruction.*;
     33 import proguard.classfile.instruction.visitor.InstructionVisitor;
     34 import proguard.classfile.util.*;
     35 
     36 import java.io.PrintStream;
     37 
     38 
     39 /**
     40  * This <code>ClassVisitor</code> prints out the complete internal
     41  * structure of the classes it visits.
     42  *
     43  * @author Eric Lafortune
     44  */
     45 public class ClassPrinter
     46 extends      SimplifiedVisitor
     47 implements   ClassVisitor,
     48              ConstantVisitor,
     49              MemberVisitor,
     50              AttributeVisitor,
     51              ExceptionInfoVisitor,
     52              InnerClassesInfoVisitor,
     53              StackMapFrameVisitor,
     54              VerificationTypeVisitor,
     55              LineNumberInfoVisitor,
     56              LocalVariableInfoVisitor,
     57              LocalVariableTypeInfoVisitor,
     58              AnnotationVisitor,
     59              ElementValueVisitor,
     60              InstructionVisitor
     61 {
     62     private static final String INDENTATION = "  ";
     63 
     64     private final PrintStream ps;
     65     private int         indentation;
     66 
     67 
     68     /**
     69      * Creates a new ClassPrinter that prints to <code>System.out</code>.
     70      */
     71     public ClassPrinter()
     72     {
     73         this(System.out);
     74     }
     75 
     76 
     77     /**
     78      * Creates a new ClassPrinter that prints to the given
     79      * <code>PrintStream</code>.
     80      */
     81     public ClassPrinter(PrintStream printStream)
     82     {
     83         ps = printStream;
     84     }
     85 
     86 
     87     // Implementations for ClassVisitor.
     88 
     89     public void visitProgramClass(ProgramClass programClass)
     90     {
     91         println("_____________________________________________________________________");
     92         println(visitorInfo(programClass) + " " +
     93                 "Program class: " + programClass.getName());
     94         indent();
     95         println("Superclass:    " + programClass.getSuperName());
     96         println("Major version: 0x" + Integer.toHexString(ClassUtil.internalMajorClassVersion(programClass.u4version)));
     97         println("Minor version: 0x" + Integer.toHexString(ClassUtil.internalMinorClassVersion(programClass.u4version)));
     98         println("Access flags:  0x" + Integer.toHexString(programClass.u2accessFlags));
     99         println("  = " +
    100                 ((programClass.u2accessFlags & ClassConstants.INTERNAL_ACC_ANNOTATTION) != 0 ? "@ " : "") +
    101                 ClassUtil.externalClassAccessFlags(programClass.u2accessFlags) +
    102                 ((programClass.u2accessFlags & ClassConstants.INTERNAL_ACC_ENUM)      != 0 ? "enum " :
    103                  (programClass.u2accessFlags & ClassConstants.INTERNAL_ACC_INTERFACE) == 0 ? "class " :
    104                                                                                              "") +
    105                 ClassUtil.externalClassName(programClass.getName()) +
    106                 (programClass.u2superClass == 0 ? "" : " extends " +
    107                 ClassUtil.externalClassName(programClass.getSuperName())));
    108         outdent();
    109         println();
    110 
    111         println("Interfaces (count = " + programClass.u2interfacesCount + "):");
    112         indent();
    113         programClass.interfaceConstantsAccept(this);
    114         outdent();
    115         println();
    116 
    117         println("Constant Pool (count = " + programClass.u2constantPoolCount + "):");
    118         indent();
    119         programClass.constantPoolEntriesAccept(this);
    120         outdent();
    121         println();
    122 
    123         println("Fields (count = " + programClass.u2fieldsCount + "):");
    124         indent();
    125         programClass.fieldsAccept(this);
    126         outdent();
    127         println();
    128 
    129         println("Methods (count = " + programClass.u2methodsCount + "):");
    130         indent();
    131         programClass.methodsAccept(this);
    132         outdent();
    133         println();
    134 
    135         println("Class file attributes (count = " + programClass.u2attributesCount + "):");
    136         indent();
    137         programClass.attributesAccept(this);
    138         outdent();
    139         println();
    140     }
    141 
    142 
    143     public void visitLibraryClass(LibraryClass libraryClass)
    144     {
    145         println("_____________________________________________________________________");
    146         println(visitorInfo(libraryClass) + " " +
    147                 "Library class: " + libraryClass.getName());
    148         indent();
    149         println("Superclass:    " + libraryClass.getSuperName());
    150         println("Access flags:  0x" + Integer.toHexString(libraryClass.u2accessFlags));
    151         println("  = " +
    152                 ((libraryClass.u2accessFlags & ClassConstants.INTERNAL_ACC_ANNOTATTION) != 0 ? "@ " : "") +
    153                 ClassUtil.externalClassAccessFlags(libraryClass.u2accessFlags) +
    154                 ((libraryClass.u2accessFlags & ClassConstants.INTERNAL_ACC_ENUM)      != 0 ? "enum " :
    155                  (libraryClass.u2accessFlags & ClassConstants.INTERNAL_ACC_INTERFACE) == 0 ? "class " :
    156                                                                                              "") +
    157                 ClassUtil.externalClassName(libraryClass.getName()) +
    158                 (libraryClass.getSuperName() == null ? "" : " extends "  +
    159                 ClassUtil.externalClassName(libraryClass.getSuperName())));
    160         outdent();
    161         println();
    162 
    163         println("Interfaces (count = " + libraryClass.interfaceClasses.length + "):");
    164         for (int index = 0; index < libraryClass.interfaceClasses.length; index++)
    165         {
    166             Clazz interfaceClass = libraryClass.interfaceClasses[index];
    167             if (interfaceClass != null)
    168             {
    169                 println("  + " + interfaceClass.getName());
    170             }
    171         }
    172 
    173         println("Fields (count = " + libraryClass.fields.length + "):");
    174         libraryClass.fieldsAccept(this);
    175 
    176         println("Methods (count = " + libraryClass.methods.length + "):");
    177         libraryClass.methodsAccept(this);
    178     }
    179 
    180 
    181     // Implementations for ConstantVisitor.
    182 
    183     public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
    184     {
    185         println(visitorInfo(integerConstant) + " Integer [" +
    186                 integerConstant.getValue() + "]");
    187     }
    188 
    189 
    190     public void visitLongConstant(Clazz clazz, LongConstant longConstant)
    191     {
    192         println(visitorInfo(longConstant) + " Long [" +
    193                 longConstant.getValue() + "]");
    194     }
    195 
    196 
    197     public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
    198     {
    199         println(visitorInfo(floatConstant) + " Float [" +
    200                 floatConstant.getValue() + "]");
    201     }
    202 
    203 
    204     public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
    205     {
    206         println(visitorInfo(doubleConstant) + " Double [" +
    207                 doubleConstant.getValue() + "]");
    208     }
    209 
    210 
    211     public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
    212     {
    213         println(visitorInfo(stringConstant) + " String [" +
    214                 clazz.getString(stringConstant.u2stringIndex) + "]");
    215     }
    216 
    217 
    218     public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)
    219     {
    220         println(visitorInfo(utf8Constant) + " Utf8 [" +
    221                 utf8Constant.getString() + "]");
    222     }
    223 
    224 
    225     public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
    226     {
    227         println(visitorInfo(fieldrefConstant) + " Fieldref [" +
    228                 clazz.getClassName(fieldrefConstant.u2classIndex)  + "." +
    229                 clazz.getName(fieldrefConstant.u2nameAndTypeIndex) + " " +
    230                 clazz.getType(fieldrefConstant.u2nameAndTypeIndex) + "]");
    231     }
    232 
    233 
    234     public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant)
    235     {
    236         println(visitorInfo(interfaceMethodrefConstant) + " InterfaceMethodref [" +
    237                 clazz.getClassName(interfaceMethodrefConstant.u2classIndex)  + "." +
    238                 clazz.getName(interfaceMethodrefConstant.u2nameAndTypeIndex) + " " +
    239                 clazz.getType(interfaceMethodrefConstant.u2nameAndTypeIndex) + "]");
    240     }
    241 
    242 
    243     public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
    244     {
    245         println(visitorInfo(methodrefConstant) + " Methodref [" +
    246                 clazz.getClassName(methodrefConstant.u2classIndex)  + "." +
    247                 clazz.getName(methodrefConstant.u2nameAndTypeIndex) + " " +
    248                 clazz.getType(methodrefConstant.u2nameAndTypeIndex) + "]");
    249     }
    250 
    251 
    252     public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
    253     {
    254         println(visitorInfo(classConstant) + " Class [" +
    255                 clazz.getString(classConstant.u2nameIndex) + "]");
    256     }
    257 
    258 
    259     public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
    260     {
    261         println(visitorInfo(nameAndTypeConstant) + " NameAndType [" +
    262                 clazz.getString(nameAndTypeConstant.u2nameIndex) + " " +
    263                 clazz.getString(nameAndTypeConstant.u2descriptorIndex) + "]");
    264     }
    265 
    266 
    267     // Implementations for MemberVisitor.
    268 
    269     public void visitProgramField(ProgramClass programClass, ProgramField programField)
    270     {
    271         println(visitorInfo(programField) + " " +
    272                 "Field:        " +
    273                 programField.getName(programClass) + " " +
    274                 programField.getDescriptor(programClass));
    275 
    276         indent();
    277         println("Access flags: 0x" + Integer.toHexString(programField.u2accessFlags));
    278         println("  = " +
    279                 ClassUtil.externalFullFieldDescription(programField.u2accessFlags,
    280                                                        programField.getName(programClass),
    281                                                        programField.getDescriptor(programClass)));
    282 
    283         visitMember(programClass, programField);
    284         outdent();
    285     }
    286 
    287 
    288     public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
    289     {
    290         println(visitorInfo(programMethod) + " " +
    291                 "Method:       " +
    292                 programMethod.getName(programClass) +
    293                 programMethod.getDescriptor(programClass));
    294 
    295         indent();
    296         println("Access flags: 0x" + Integer.toHexString(programMethod.u2accessFlags));
    297         println("  = " +
    298                 ClassUtil.externalFullMethodDescription(programClass.getName(),
    299                                                         programMethod.u2accessFlags,
    300                                                         programMethod.getName(programClass),
    301                                                         programMethod.getDescriptor(programClass)));
    302 
    303         visitMember(programClass, programMethod);
    304         outdent();
    305     }
    306 
    307 
    308     private void visitMember(ProgramClass programClass, ProgramMember programMember)
    309     {
    310         if (programMember.u2attributesCount > 0)
    311         {
    312             println("Class member attributes (count = " + programMember.u2attributesCount + "):");
    313             programMember.attributesAccept(programClass, this);
    314         }
    315     }
    316 
    317 
    318     public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
    319     {
    320         println(visitorInfo(libraryField) + " " +
    321                 "Field:        " +
    322                 libraryField.getName(libraryClass) + " " +
    323                 libraryField.getDescriptor(libraryClass));
    324 
    325         indent();
    326         println("Access flags: 0x" + Integer.toHexString(libraryField.u2accessFlags));
    327         println("  = " +
    328                 ClassUtil.externalFullFieldDescription(libraryField.u2accessFlags,
    329                                                        libraryField.getName(libraryClass),
    330                                                        libraryField.getDescriptor(libraryClass)));
    331         outdent();
    332     }
    333 
    334 
    335     public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
    336     {
    337         println(visitorInfo(libraryMethod) + " " +
    338                 "Method:       " +
    339                 libraryMethod.getName(libraryClass) + " " +
    340                 libraryMethod.getDescriptor(libraryClass));
    341 
    342         indent();
    343         println("Access flags: 0x" + Integer.toHexString(libraryMethod.u2accessFlags));
    344         println("  = " +
    345                 ClassUtil.externalFullMethodDescription(libraryClass.getName(),
    346                                                         libraryMethod.u2accessFlags,
    347                                                         libraryMethod.getName(libraryClass),
    348                                                         libraryMethod.getDescriptor(libraryClass)));
    349         outdent();
    350     }
    351 
    352 
    353     // Implementations for AttributeVisitor.
    354     // Note that attributes are typically only referenced once, so we don't
    355     // test if they are marked already.
    356 
    357     public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
    358     {
    359         println(visitorInfo(unknownAttribute) +
    360                 " Unknown attribute (" + clazz.getString(unknownAttribute.u2attributeNameIndex) + ")");
    361     }
    362 
    363 
    364     public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
    365     {
    366         println(visitorInfo(sourceFileAttribute) +
    367                 " Source file attribute:");
    368 
    369         indent();
    370         clazz.constantPoolEntryAccept(sourceFileAttribute.u2sourceFileIndex, this);
    371         outdent();
    372     }
    373 
    374 
    375     public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
    376     {
    377         println(visitorInfo(sourceDirAttribute) +
    378                 " Source dir attribute:");
    379 
    380         indent();
    381         clazz.constantPoolEntryAccept(sourceDirAttribute.u2sourceDirIndex, this);
    382         outdent();
    383     }
    384 
    385 
    386     public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
    387     {
    388         println(visitorInfo(innerClassesAttribute) +
    389                 " Inner classes attribute (count = " + innerClassesAttribute.u2classesCount + ")");
    390 
    391         indent();
    392         innerClassesAttribute.innerClassEntriesAccept(clazz, this);
    393         outdent();
    394     }
    395 
    396 
    397     public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
    398     {
    399         println(visitorInfo(enclosingMethodAttribute) +
    400                 " Enclosing method attribute:");
    401 
    402         indent();
    403         clazz.constantPoolEntryAccept(enclosingMethodAttribute.u2classIndex, this);
    404 
    405         if (enclosingMethodAttribute.u2nameAndTypeIndex != 0)
    406         {
    407             clazz.constantPoolEntryAccept(enclosingMethodAttribute.u2nameAndTypeIndex, this);
    408         }
    409         outdent();
    410     }
    411 
    412 
    413     public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)
    414     {
    415         println(visitorInfo(deprecatedAttribute) +
    416                 " Deprecated attribute");
    417     }
    418 
    419 
    420     public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)
    421     {
    422         println(visitorInfo(syntheticAttribute) +
    423                 " Synthetic attribute");
    424     }
    425 
    426 
    427     public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
    428     {
    429         println(visitorInfo(signatureAttribute) +
    430                 " Signature attribute:");
    431 
    432         indent();
    433         clazz.constantPoolEntryAccept(signatureAttribute.u2signatureIndex, this);
    434         outdent();
    435     }
    436 
    437 
    438     public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
    439     {
    440         println(visitorInfo(constantValueAttribute) +
    441                 " Constant value attribute:");
    442 
    443         clazz.constantPoolEntryAccept(constantValueAttribute.u2constantValueIndex, this);
    444     }
    445 
    446 
    447     public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
    448     {
    449         println(visitorInfo(exceptionsAttribute) +
    450                 " Exceptions attribute (count = " + exceptionsAttribute.u2exceptionIndexTableLength + ")");
    451 
    452         indent();
    453         exceptionsAttribute.exceptionEntriesAccept((ProgramClass)clazz, this);
    454         outdent();
    455     }
    456 
    457 
    458     public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
    459     {
    460         println(visitorInfo(codeAttribute) +
    461                 " Code attribute instructions (code length = "+ codeAttribute.u4codeLength +
    462                 ", locals = "+ codeAttribute.u2maxLocals +
    463                 ", stack = "+ codeAttribute.u2maxStack + "):");
    464 
    465         indent();
    466 
    467         codeAttribute.instructionsAccept(clazz, method, this);
    468 
    469         println("Code attribute exceptions (count = " +
    470                 codeAttribute.u2exceptionTableLength + "):");
    471 
    472         codeAttribute.exceptionsAccept(clazz, method, this);
    473 
    474         println("Code attribute attributes (attribute count = " +
    475                 codeAttribute.u2attributesCount + "):");
    476 
    477         codeAttribute.attributesAccept(clazz, method, this);
    478 
    479         outdent();
    480     }
    481 
    482 
    483     public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
    484     {
    485         println(visitorInfo(codeAttribute) +
    486                 " Stack map attribute (count = "+
    487                 stackMapAttribute.u2stackMapFramesCount + "):");
    488 
    489         indent();
    490         stackMapAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this);
    491         outdent();
    492     }
    493 
    494 
    495     public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
    496     {
    497         println(visitorInfo(codeAttribute) +
    498                 " Stack map table attribute (count = "+
    499                 stackMapTableAttribute.u2stackMapFramesCount + "):");
    500 
    501         indent();
    502         stackMapTableAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this);
    503         outdent();
    504     }
    505 
    506 
    507     public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
    508     {
    509         println(visitorInfo(lineNumberTableAttribute) +
    510                 " Line number table attribute (count = " +
    511                 lineNumberTableAttribute.u2lineNumberTableLength + ")");
    512 
    513         indent();
    514         lineNumberTableAttribute.lineNumbersAccept(clazz, method, codeAttribute, this);
    515         outdent();
    516     }
    517 
    518 
    519     public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
    520     {
    521         println(visitorInfo(localVariableTableAttribute) +
    522                 " Local variable table attribute (count = " +
    523                 localVariableTableAttribute.u2localVariableTableLength + ")");
    524 
    525         indent();
    526         localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
    527         outdent();
    528     }
    529 
    530 
    531     public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
    532     {
    533         println(visitorInfo(localVariableTypeTableAttribute) +
    534                 " Local variable type table attribute (count = "+
    535                 localVariableTypeTableAttribute.u2localVariableTypeTableLength + ")");
    536 
    537         indent();
    538         localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
    539         outdent();
    540     }
    541 
    542 
    543     public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
    544     {
    545         println(visitorInfo(runtimeVisibleAnnotationsAttribute) +
    546                 " Runtime visible annotations attribute:");
    547 
    548         indent();
    549         runtimeVisibleAnnotationsAttribute.annotationsAccept(clazz, this);
    550         outdent();
    551     }
    552 
    553 
    554     public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
    555     {
    556         println(visitorInfo(runtimeInvisibleAnnotationsAttribute) +
    557                 " Runtime invisible annotations attribute:");
    558 
    559         indent();
    560         runtimeInvisibleAnnotationsAttribute.annotationsAccept(clazz, this);
    561         outdent();
    562     }
    563 
    564 
    565     public void visitRuntimeVisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute)
    566     {
    567         println(visitorInfo(runtimeVisibleParameterAnnotationsAttribute) +
    568                 " Runtime visible parameter annotations attribute (parameter count = " + runtimeVisibleParameterAnnotationsAttribute.u2parametersCount + "):");
    569 
    570         indent();
    571         runtimeVisibleParameterAnnotationsAttribute.annotationsAccept(clazz, method, this);
    572         outdent();
    573     }
    574 
    575 
    576     public void visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute)
    577     {
    578         println(visitorInfo(runtimeInvisibleParameterAnnotationsAttribute) +
    579                 " Runtime invisible parameter annotations attribute (parameter count = " + runtimeInvisibleParameterAnnotationsAttribute.u2parametersCount + "):");
    580 
    581         indent();
    582         runtimeInvisibleParameterAnnotationsAttribute.annotationsAccept(clazz, method, this);
    583         outdent();
    584     }
    585 
    586 
    587     public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
    588     {
    589         println(visitorInfo(annotationDefaultAttribute) +
    590                 " Annotation default attribute:");
    591 
    592         indent();
    593         annotationDefaultAttribute.defaultValueAccept(clazz, this);
    594         outdent();
    595     }
    596 
    597 
    598     // Implementations for InnerClassesInfoVisitor.
    599 
    600     public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
    601     {
    602         println(visitorInfo(innerClassesInfo) +
    603                 " InnerClassesInfo:");
    604 
    605         indent();
    606         innerClassesInfo.innerClassConstantAccept(clazz, this);
    607         innerClassesInfo.outerClassConstantAccept(clazz, this);
    608         innerClassesInfo.innerNameConstantAccept(clazz, this);
    609         outdent();
    610     }
    611 
    612 
    613     // Implementations for InstructionVisitor.
    614 
    615     public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction)
    616     {
    617         println(instruction.toString(offset));
    618     }
    619 
    620 
    621     public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
    622     {
    623         println(constantInstruction.toString(offset));
    624 
    625         indent();
    626         clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
    627         outdent();
    628     }
    629 
    630 
    631     public void visitTableSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction)
    632     {
    633         println(tableSwitchInstruction.toString(offset));
    634 
    635         indent();
    636 
    637         int[] jumpOffsets = tableSwitchInstruction.jumpOffsets;
    638 
    639         for (int index = 0; index < jumpOffsets.length; index++)
    640         {
    641             int jumpOffset = jumpOffsets[index];
    642             println(Integer.toString(tableSwitchInstruction.lowCase + index)  + ": offset = " + jumpOffset + ", target = " + (offset + jumpOffset));
    643         }
    644 
    645         int defaultOffset = tableSwitchInstruction.defaultOffset;
    646         println("default: offset = " + defaultOffset + ", target = "+ (offset + defaultOffset));
    647 
    648         outdent();
    649     }
    650 
    651 
    652     public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction)
    653     {
    654         println(lookUpSwitchInstruction.toString(offset));
    655 
    656         indent();
    657 
    658         int[] cases       = lookUpSwitchInstruction.cases;
    659         int[] jumpOffsets = lookUpSwitchInstruction.jumpOffsets;
    660 
    661         for (int index = 0; index < jumpOffsets.length; index++)
    662         {
    663             int jumpOffset = jumpOffsets[index];
    664             println(Integer.toString(cases[index])  + ": offset = " + jumpOffset + ", target = " + (offset + jumpOffset));
    665         }
    666 
    667         int defaultOffset = lookUpSwitchInstruction.defaultOffset;
    668         println("default: offset = " + defaultOffset + ", target = "+ (offset + defaultOffset));
    669 
    670         outdent();
    671     }
    672 
    673 
    674     // Implementations for ExceptionInfoVisitor.
    675 
    676     public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
    677     {
    678         println(visitorInfo(exceptionInfo) +
    679                 " ExceptionInfo (" +
    680                 exceptionInfo.u2startPC + " -> " +
    681                 exceptionInfo.u2endPC + ": " +
    682                 exceptionInfo.u2handlerPC + "):");
    683 
    684         if (exceptionInfo.u2catchType != 0)
    685         {
    686             clazz.constantPoolEntryAccept(exceptionInfo.u2catchType, this);
    687         }
    688     }
    689 
    690 
    691     // Implementations for StackMapFrameVisitor.
    692 
    693     public void visitSameZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameZeroFrame sameZeroFrame)
    694     {
    695         println(visitorInfo(sameZeroFrame) +
    696                 " [" + offset  + "]" +
    697                 " Var: ..., Stack: (empty)");
    698     }
    699 
    700 
    701     public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame)
    702     {
    703         print(visitorInfo(sameOneFrame) +
    704               " [" + offset  + "]" +
    705               " Var: ..., Stack: ");
    706 
    707         sameOneFrame.stackItemAccept(clazz, method, codeAttribute, offset, this);
    708 
    709         println();
    710     }
    711 
    712 
    713     public void visitLessZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LessZeroFrame lessZeroFrame)
    714     {
    715         println(visitorInfo(lessZeroFrame) +
    716                 " [" + offset  + "]" +
    717                 " Var: -" + lessZeroFrame.choppedVariablesCount +
    718                 ", Stack: (empty)");
    719     }
    720 
    721 
    722     public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame)
    723     {
    724         print(visitorInfo(moreZeroFrame) +
    725               " [" + offset  + "]" +
    726               " Var: ...");
    727 
    728         moreZeroFrame.additionalVariablesAccept(clazz, method, codeAttribute, offset, this);
    729 
    730         ps.println(", Stack: (empty)");
    731     }
    732 
    733 
    734     public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame)
    735     {
    736         print(visitorInfo(fullFrame) +
    737               " [" + offset  + "]" +
    738               " Var: ");
    739 
    740         fullFrame.variablesAccept(clazz, method, codeAttribute, offset, this);
    741 
    742         ps.print(", Stack: ");
    743 
    744         fullFrame.stackAccept(clazz, method, codeAttribute, offset, this);
    745 
    746         println();
    747     }
    748 
    749 
    750     // Implementations for VerificationTypeVisitor.
    751 
    752     public void visitIntegerType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, IntegerType integerType)
    753     {
    754         ps.print("[i]");
    755     }
    756 
    757 
    758     public void visitFloatType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FloatType floatType)
    759     {
    760         ps.print("[f]");
    761     }
    762 
    763 
    764     public void visitLongType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LongType longType)
    765     {
    766         ps.print("[l]");
    767     }
    768 
    769 
    770     public void visitDoubleType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, DoubleType doubleType)
    771     {
    772         ps.print("[d]");
    773     }
    774 
    775 
    776     public void visitTopType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TopType topType)
    777     {
    778         ps.print("[T]");
    779     }
    780 
    781 
    782     public void visitObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType)
    783     {
    784         ps.print("[a:" + clazz.getClassName(objectType.u2classIndex) + "]");
    785     }
    786 
    787 
    788     public void visitNullType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, NullType nullType)
    789     {
    790         ps.print("[n]");
    791     }
    792 
    793 
    794     public void visitUninitializedType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, UninitializedType uninitializedType)
    795     {
    796         ps.print("[u:" + uninitializedType.u2newInstructionOffset + "]");
    797     }
    798 
    799 
    800     public void visitUninitializedThisType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, UninitializedThisType uninitializedThisType)
    801     {
    802         ps.print("[u:this]");
    803     }
    804 
    805 
    806     // Implementations for LineNumberInfoVisitor.
    807 
    808     public void visitLineNumberInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberInfo lineNumberInfo)
    809     {
    810         println("[" + lineNumberInfo.u2startPC + "] -> line " +
    811                 lineNumberInfo.u2lineNumber);
    812     }
    813 
    814 
    815     // Implementations for LocalVariableInfoVisitor.
    816 
    817     public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
    818     {
    819         println("#" + localVariableInfo.u2index + ": " +
    820                 localVariableInfo.u2startPC + " -> " +
    821                 (localVariableInfo.u2startPC + localVariableInfo.u2length) + " [" +
    822                 clazz.getString(localVariableInfo.u2descriptorIndex) + " " +
    823                 clazz.getString(localVariableInfo.u2nameIndex) + "]");
    824     }
    825 
    826 
    827     // Implementations for LocalVariableTypeInfoVisitor.
    828 
    829     public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
    830     {
    831         println("#" + localVariableTypeInfo.u2index + ": " +
    832                 localVariableTypeInfo.u2startPC + " -> " +
    833                 (localVariableTypeInfo.u2startPC + localVariableTypeInfo.u2length) + " [" +
    834                 clazz.getString(localVariableTypeInfo.u2signatureIndex) + " " +
    835                 clazz.getString(localVariableTypeInfo.u2nameIndex) + "]");
    836     }
    837 
    838 
    839     // Implementations for AnnotationVisitor.
    840 
    841     public void visitAnnotation(Clazz clazz, Annotation annotation)
    842     {
    843         println(visitorInfo(annotation) +
    844                 " Annotation [" + clazz.getString(annotation.u2typeIndex) + "]:");
    845 
    846         indent();
    847         annotation.elementValuesAccept(clazz, this);
    848         outdent();
    849     }
    850 
    851 
    852     // Implementations for ElementValueVisitor.
    853 
    854     public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue)
    855     {
    856         println(visitorInfo(constantElementValue) +
    857                 " Constant element value [" +
    858                 (constantElementValue.u2elementNameIndex == 0 ? "(default)" :
    859                 clazz.getString(constantElementValue.u2elementNameIndex)) + " '" +
    860                 constantElementValue.u1tag + "']");
    861 
    862         indent();
    863         clazz.constantPoolEntryAccept(constantElementValue.u2constantValueIndex, this);
    864         outdent();
    865     }
    866 
    867 
    868     public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
    869     {
    870         println(visitorInfo(enumConstantElementValue) +
    871                 " Enum constant element value [" +
    872                 (enumConstantElementValue.u2elementNameIndex == 0 ? "(default)" :
    873                 clazz.getString(enumConstantElementValue.u2elementNameIndex)) + ", " +
    874                 clazz.getString(enumConstantElementValue.u2typeNameIndex)  + ", " +
    875                 clazz.getString(enumConstantElementValue.u2constantNameIndex) + "]");
    876     }
    877 
    878 
    879     public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)
    880     {
    881         println(visitorInfo(classElementValue) +
    882                 " Class element value [" +
    883                 (classElementValue.u2elementNameIndex == 0 ? "(default)" :
    884                 clazz.getString(classElementValue.u2elementNameIndex)) + ", " +
    885                 clazz.getString(classElementValue.u2classInfoIndex) + "]");
    886     }
    887 
    888 
    889     public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)
    890     {
    891         println(visitorInfo(annotationElementValue) +
    892                 " Annotation element value [" +
    893                 (annotationElementValue.u2elementNameIndex == 0 ? "(default)" :
    894                 clazz.getString(annotationElementValue.u2elementNameIndex)) + "]:");
    895 
    896         indent();
    897         annotationElementValue.annotationAccept(clazz, this);
    898         outdent();
    899     }
    900 
    901 
    902     public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
    903     {
    904         println(visitorInfo(arrayElementValue) +
    905                 " Array element value [" +
    906                 (arrayElementValue.u2elementNameIndex == 0 ? "(default)" :
    907                 clazz.getString(arrayElementValue.u2elementNameIndex)) + "]:");
    908 
    909         indent();
    910         arrayElementValue.elementValuesAccept(clazz, annotation, this);
    911         outdent();
    912     }
    913 
    914 
    915     // Small utility methods.
    916 
    917     private void indent()
    918     {
    919         indentation++;
    920     }
    921 
    922     private void outdent()
    923     {
    924         indentation--;
    925     }
    926 
    927     private void println(String string)
    928     {
    929         print(string);
    930         println();
    931 
    932     }
    933 
    934     private void print(String string)
    935     {
    936         for (int index = 0; index < indentation; index++)
    937         {
    938             ps.print(INDENTATION);
    939         }
    940 
    941         ps.print(string);
    942     }
    943 
    944     private void println()
    945     {
    946         ps.println();
    947     }
    948 
    949 
    950     private String visitorInfo(VisitorAccepter visitorAccepter)
    951     {
    952         return visitorAccepter.getVisitorInfo() == null ? "-" : "+";
    953     }
    954 }
    955