diff options
Diffstat (limited to 'third_party/java/proguard/proguard5.3.3/src/proguard/classfile/visitor/ClassPrinter.java')
-rw-r--r-- | third_party/java/proguard/proguard5.3.3/src/proguard/classfile/visitor/ClassPrinter.java | 1183 |
1 files changed, 1183 insertions, 0 deletions
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/classfile/visitor/ClassPrinter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/classfile/visitor/ClassPrinter.java new file mode 100644 index 0000000000..c14a67d9a7 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/classfile/visitor/ClassPrinter.java @@ -0,0 +1,1183 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package proguard.classfile.visitor; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.annotation.*; +import proguard.classfile.attribute.annotation.target.*; +import proguard.classfile.attribute.annotation.target.visitor.*; +import proguard.classfile.attribute.annotation.visitor.*; +import proguard.classfile.attribute.preverification.*; +import proguard.classfile.attribute.preverification.visitor.*; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.*; + +import java.io.PrintStream; + + +/** + * This <code>ClassVisitor</code> prints out the complete internal + * structure of the classes it visits. + * + * @author Eric Lafortune + */ +public class ClassPrinter +extends SimplifiedVisitor +implements ClassVisitor, + ConstantVisitor, + MemberVisitor, + AttributeVisitor, + BootstrapMethodInfoVisitor, + InnerClassesInfoVisitor, + ExceptionInfoVisitor, + StackMapFrameVisitor, + VerificationTypeVisitor, + LineNumberInfoVisitor, + ParameterInfoVisitor, + LocalVariableInfoVisitor, + LocalVariableTypeInfoVisitor, + AnnotationVisitor, + TypeAnnotationVisitor, + TargetInfoVisitor, + LocalVariableTargetElementVisitor, + TypePathInfoVisitor, + ElementValueVisitor, + InstructionVisitor +{ + private static final String INDENTATION = " "; + + private final PrintStream ps; + + private int indentation; + + + /** + * Creates a new ClassPrinter that prints to <code>System.out</code>. + */ + public ClassPrinter() + { + this(System.out); + } + + + /** + * Creates a new ClassPrinter that prints to the given + * <code>PrintStream</code>. + */ + public ClassPrinter(PrintStream printStream) + { + ps = printStream; + } + + + // Implementations for ClassVisitor. + + public void visitProgramClass(ProgramClass programClass) + { + println("_____________________________________________________________________"); + println(visitorInfo(programClass) + " " + + "Program class: " + programClass.getName()); + indent(); + println("Superclass: " + programClass.getSuperName()); + println("Major version: 0x" + Integer.toHexString(ClassUtil.internalMajorClassVersion(programClass.u4version))); + println("Minor version: 0x" + Integer.toHexString(ClassUtil.internalMinorClassVersion(programClass.u4version))); + println(" = target " + ClassUtil.externalClassVersion(programClass.u4version)); + println("Access flags: 0x" + Integer.toHexString(programClass.u2accessFlags)); + println(" = " + + ((programClass.u2accessFlags & ClassConstants.ACC_ANNOTATTION) != 0 ? "@ " : "") + + ClassUtil.externalClassAccessFlags(programClass.u2accessFlags) + + ((programClass.u2accessFlags & ClassConstants.ACC_ENUM) != 0 ? "enum " : + (programClass.u2accessFlags & ClassConstants.ACC_INTERFACE) == 0 ? "class " : + "") + + ClassUtil.externalClassName(programClass.getName()) + + (programClass.u2superClass == 0 ? "" : " extends " + + ClassUtil.externalClassName(programClass.getSuperName()))); + outdent(); + println(); + + println("Interfaces (count = " + programClass.u2interfacesCount + "):"); + indent(); + programClass.interfaceConstantsAccept(this); + outdent(); + println(); + + println("Constant Pool (count = " + programClass.u2constantPoolCount + "):"); + indent(); + programClass.constantPoolEntriesAccept(this); + outdent(); + println(); + + println("Fields (count = " + programClass.u2fieldsCount + "):"); + indent(); + programClass.fieldsAccept(this); + outdent(); + println(); + + println("Methods (count = " + programClass.u2methodsCount + "):"); + indent(); + programClass.methodsAccept(this); + outdent(); + println(); + + println("Class file attributes (count = " + programClass.u2attributesCount + "):"); + indent(); + programClass.attributesAccept(this); + outdent(); + println(); + } + + + public void visitLibraryClass(LibraryClass libraryClass) + { + println("_____________________________________________________________________"); + println(visitorInfo(libraryClass) + " " + + "Library class: " + libraryClass.getName()); + indent(); + println("Superclass: " + libraryClass.getSuperName()); + println("Access flags: 0x" + Integer.toHexString(libraryClass.u2accessFlags)); + println(" = " + + ((libraryClass.u2accessFlags & ClassConstants.ACC_ANNOTATTION) != 0 ? "@ " : "") + + ClassUtil.externalClassAccessFlags(libraryClass.u2accessFlags) + + ((libraryClass.u2accessFlags & ClassConstants.ACC_ENUM) != 0 ? "enum " : + (libraryClass.u2accessFlags & ClassConstants.ACC_INTERFACE) == 0 ? "class " : + "") + + ClassUtil.externalClassName(libraryClass.getName()) + + (libraryClass.getSuperName() == null ? "" : " extends " + + ClassUtil.externalClassName(libraryClass.getSuperName()))); + outdent(); + println(); + + println("Interfaces (count = " + libraryClass.interfaceClasses.length + "):"); + for (int index = 0; index < libraryClass.interfaceClasses.length; index++) + { + Clazz interfaceClass = libraryClass.interfaceClasses[index]; + if (interfaceClass != null) + { + println(" + " + interfaceClass.getName()); + } + } + + println("Fields (count = " + libraryClass.fields.length + "):"); + libraryClass.fieldsAccept(this); + + println("Methods (count = " + libraryClass.methods.length + "):"); + libraryClass.methodsAccept(this); + } + + + // Implementations for ConstantVisitor. + + public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant) + { + println(visitorInfo(integerConstant) + " Integer [" + + integerConstant.getValue() + "]"); + } + + + public void visitLongConstant(Clazz clazz, LongConstant longConstant) + { + println(visitorInfo(longConstant) + " Long [" + + longConstant.getValue() + "]"); + } + + + public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant) + { + println(visitorInfo(floatConstant) + " Float [" + + floatConstant.getValue() + "]"); + } + + + public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant) + { + println(visitorInfo(doubleConstant) + " Double [" + + doubleConstant.getValue() + "]"); + } + + + public void visitStringConstant(Clazz clazz, StringConstant stringConstant) + { + println(visitorInfo(stringConstant) + " String [" + + stringConstant.getString(clazz) + "]"); + } + + + public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant) + { + println(visitorInfo(utf8Constant) + " Utf8 [" + + utf8Constant.getString() + "]"); + } + + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) + { + println(visitorInfo(invokeDynamicConstant) + " InvokeDynamic [bootstrap method index = " + invokeDynamicConstant.u2bootstrapMethodAttributeIndex + "]:"); + + indent(); + clazz.constantPoolEntryAccept(invokeDynamicConstant.u2nameAndTypeIndex, this); + outdent(); + } + + + public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) + { + println(visitorInfo(methodHandleConstant) + " MethodHandle [kind = " + methodHandleConstant.u1referenceKind + "]:"); + + indent(); + clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this); + outdent(); + } + + + public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) + { + println(visitorInfo(fieldrefConstant) + " Fieldref [" + + clazz.getClassName(fieldrefConstant.u2classIndex) + "." + + clazz.getName(fieldrefConstant.u2nameAndTypeIndex) + " " + + clazz.getType(fieldrefConstant.u2nameAndTypeIndex) + "]"); + } + + + public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant) + { + println(visitorInfo(interfaceMethodrefConstant) + " InterfaceMethodref [" + + clazz.getClassName(interfaceMethodrefConstant.u2classIndex) + "." + + clazz.getName(interfaceMethodrefConstant.u2nameAndTypeIndex) + " " + + clazz.getType(interfaceMethodrefConstant.u2nameAndTypeIndex) + "]"); + } + + + public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant) + { + println(visitorInfo(methodrefConstant) + " Methodref [" + + clazz.getClassName(methodrefConstant.u2classIndex) + "." + + clazz.getName(methodrefConstant.u2nameAndTypeIndex) + " " + + clazz.getType(methodrefConstant.u2nameAndTypeIndex) + "]"); + } + + + public void visitClassConstant(Clazz clazz, ClassConstant classConstant) + { + println(visitorInfo(classConstant) + " Class [" + + classConstant.getName(clazz) + "]"); + } + + + public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) + { + println(visitorInfo(methodTypeConstant) + " MethodType [" + + methodTypeConstant.getType(clazz) + "]"); + } + + + public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) + { + println(visitorInfo(nameAndTypeConstant) + " NameAndType [" + + nameAndTypeConstant.getName(clazz) + " " + + nameAndTypeConstant.getType(clazz) + "]"); + } + + + // Implementations for MemberVisitor. + + public void visitProgramField(ProgramClass programClass, ProgramField programField) + { + println(visitorInfo(programField) + " " + + "Field: " + + programField.getName(programClass) + " " + + programField.getDescriptor(programClass)); + + indent(); + println("Access flags: 0x" + Integer.toHexString(programField.u2accessFlags)); + println(" = " + + ClassUtil.externalFullFieldDescription(programField.u2accessFlags, + programField.getName(programClass), + programField.getDescriptor(programClass))); + + visitMember(programClass, programField); + outdent(); + } + + + public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) + { + println(visitorInfo(programMethod) + " " + + "Method: " + + programMethod.getName(programClass) + + programMethod.getDescriptor(programClass)); + + indent(); + println("Access flags: 0x" + Integer.toHexString(programMethod.u2accessFlags)); + println(" = " + + ClassUtil.externalFullMethodDescription(programClass.getName(), + programMethod.u2accessFlags, + programMethod.getName(programClass), + programMethod.getDescriptor(programClass))); + + visitMember(programClass, programMethod); + outdent(); + } + + + private void visitMember(ProgramClass programClass, ProgramMember programMember) + { + if (programMember.u2attributesCount > 0) + { + println("Class member attributes (count = " + programMember.u2attributesCount + "):"); + programMember.attributesAccept(programClass, this); + } + } + + + public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField) + { + println(visitorInfo(libraryField) + " " + + "Field: " + + libraryField.getName(libraryClass) + " " + + libraryField.getDescriptor(libraryClass)); + + indent(); + println("Access flags: 0x" + Integer.toHexString(libraryField.u2accessFlags)); + println(" = " + + ClassUtil.externalFullFieldDescription(libraryField.u2accessFlags, + libraryField.getName(libraryClass), + libraryField.getDescriptor(libraryClass))); + outdent(); + } + + + public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) + { + println(visitorInfo(libraryMethod) + " " + + "Method: " + + libraryMethod.getName(libraryClass) + " " + + libraryMethod.getDescriptor(libraryClass)); + + indent(); + println("Access flags: 0x" + Integer.toHexString(libraryMethod.u2accessFlags)); + println(" = " + + ClassUtil.externalFullMethodDescription(libraryClass.getName(), + libraryMethod.u2accessFlags, + libraryMethod.getName(libraryClass), + libraryMethod.getDescriptor(libraryClass))); + outdent(); + } + + + // Implementations for AttributeVisitor. + // Note that attributes are typically only referenced once, so we don't + // test if they are marked already. + + public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute) + { + println(visitorInfo(unknownAttribute) + + " Unknown attribute (" + unknownAttribute.getAttributeName(clazz) + ")"); + } + + + public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) + { + println(visitorInfo(bootstrapMethodsAttribute) + + " Bootstrap methods attribute (count = " + bootstrapMethodsAttribute.u2bootstrapMethodsCount + "):"); + + indent(); + bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this); + outdent(); + } + + + public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) + { + println(visitorInfo(sourceFileAttribute) + + " Source file attribute:"); + + indent(); + clazz.constantPoolEntryAccept(sourceFileAttribute.u2sourceFileIndex, this); + outdent(); + } + + + public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute) + { + println(visitorInfo(sourceDirAttribute) + + " Source dir attribute:"); + + indent(); + clazz.constantPoolEntryAccept(sourceDirAttribute.u2sourceDirIndex, this); + outdent(); + } + + + public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute) + { + println(visitorInfo(innerClassesAttribute) + + " Inner classes attribute (count = " + innerClassesAttribute.u2classesCount + ")"); + + indent(); + innerClassesAttribute.innerClassEntriesAccept(clazz, this); + outdent(); + } + + + public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute) + { + println(visitorInfo(enclosingMethodAttribute) + + " Enclosing method attribute:"); + + indent(); + clazz.constantPoolEntryAccept(enclosingMethodAttribute.u2classIndex, this); + + if (enclosingMethodAttribute.u2nameAndTypeIndex != 0) + { + clazz.constantPoolEntryAccept(enclosingMethodAttribute.u2nameAndTypeIndex, this); + } + outdent(); + } + + + public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute) + { + println(visitorInfo(deprecatedAttribute) + + " Deprecated attribute"); + } + + + public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute) + { + println(visitorInfo(syntheticAttribute) + + " Synthetic attribute"); + } + + + public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute) + { + println(visitorInfo(signatureAttribute) + + " Signature attribute:"); + + indent(); + clazz.constantPoolEntryAccept(signatureAttribute.u2signatureIndex, this); + outdent(); + } + + + public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute) + { + println(visitorInfo(constantValueAttribute) + + " Constant value attribute:"); + + clazz.constantPoolEntryAccept(constantValueAttribute.u2constantValueIndex, this); + } + + + public void visitMethodParametersAttribute(Clazz clazz, Method method, MethodParametersAttribute methodParametersAttribute) + { + println(visitorInfo(methodParametersAttribute) + + " Method parameters attribute (count = " + methodParametersAttribute.u1parametersCount + ")"); + + indent(); + methodParametersAttribute.parametersAccept(clazz, method, this); + outdent(); + } + + + public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute) + { + println(visitorInfo(exceptionsAttribute) + + " Exceptions attribute (count = " + exceptionsAttribute.u2exceptionIndexTableLength + ")"); + + indent(); + exceptionsAttribute.exceptionEntriesAccept((ProgramClass)clazz, this); + outdent(); + } + + + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) + { + println(visitorInfo(codeAttribute) + + " Code attribute instructions (code length = "+ codeAttribute.u4codeLength + + ", locals = "+ codeAttribute.u2maxLocals + + ", stack = "+ codeAttribute.u2maxStack + "):"); + + indent(); + + codeAttribute.instructionsAccept(clazz, method, this); + + println("Code attribute exceptions (count = " + + codeAttribute.u2exceptionTableLength + "):"); + + codeAttribute.exceptionsAccept(clazz, method, this); + + println("Code attribute attributes (attribute count = " + + codeAttribute.u2attributesCount + "):"); + + codeAttribute.attributesAccept(clazz, method, this); + + outdent(); + } + + + public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute) + { + println(visitorInfo(codeAttribute) + + " Stack map attribute (count = "+ + stackMapAttribute.u2stackMapFramesCount + "):"); + + indent(); + stackMapAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this); + outdent(); + } + + + public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute) + { + println(visitorInfo(codeAttribute) + + " Stack map table attribute (count = "+ + stackMapTableAttribute.u2stackMapFramesCount + "):"); + + indent(); + stackMapTableAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this); + outdent(); + } + + + public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute) + { + println(visitorInfo(lineNumberTableAttribute) + + " Line number table attribute (count = " + + lineNumberTableAttribute.u2lineNumberTableLength + ")"); + + indent(); + lineNumberTableAttribute.lineNumbersAccept(clazz, method, codeAttribute, this); + outdent(); + } + + + public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute) + { + println(visitorInfo(localVariableTableAttribute) + + " Local variable table attribute (count = " + + localVariableTableAttribute.u2localVariableTableLength + ")"); + + indent(); + localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); + outdent(); + } + + + public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute) + { + println(visitorInfo(localVariableTypeTableAttribute) + + " Local variable type table attribute (count = "+ + localVariableTypeTableAttribute.u2localVariableTypeTableLength + ")"); + + indent(); + localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); + outdent(); + } + + + public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute) + { + println(visitorInfo(runtimeVisibleAnnotationsAttribute) + + " Runtime visible annotations attribute:"); + + indent(); + runtimeVisibleAnnotationsAttribute.annotationsAccept(clazz, this); + outdent(); + } + + + public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute) + { + println(visitorInfo(runtimeInvisibleAnnotationsAttribute) + + " Runtime invisible annotations attribute:"); + + indent(); + runtimeInvisibleAnnotationsAttribute.annotationsAccept(clazz, this); + outdent(); + } + + + public void visitRuntimeVisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute) + { + println(visitorInfo(runtimeVisibleParameterAnnotationsAttribute) + + " Runtime visible parameter annotations attribute (parameter count = " + runtimeVisibleParameterAnnotationsAttribute.u1parametersCount + "):"); + + indent(); + runtimeVisibleParameterAnnotationsAttribute.annotationsAccept(clazz, method, this); + outdent(); + } + + + public void visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute) + { + println(visitorInfo(runtimeInvisibleParameterAnnotationsAttribute) + + " Runtime invisible parameter annotations attribute (parameter count = " + runtimeInvisibleParameterAnnotationsAttribute.u1parametersCount + "):"); + + indent(); + runtimeInvisibleParameterAnnotationsAttribute.annotationsAccept(clazz, method, this); + outdent(); + } + + + public void visitRuntimeVisibleTypeAnnotationsAttribute(Clazz clazz, RuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute) + { + println(visitorInfo(runtimeVisibleTypeAnnotationsAttribute) + + " Runtime visible type annotations attribute"); + + indent(); + runtimeVisibleTypeAnnotationsAttribute.typeAnnotationsAccept(clazz, this); + outdent(); + } + + + public void visitRuntimeInvisibleTypeAnnotationsAttribute(Clazz clazz, RuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute) + { + println(visitorInfo(runtimeInvisibleTypeAnnotationsAttribute) + + " Runtime invisible type annotations attribute"); + + indent(); + runtimeInvisibleTypeAnnotationsAttribute.typeAnnotationsAccept(clazz, this); + outdent(); + } + + + public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute) + { + println(visitorInfo(annotationDefaultAttribute) + + " Annotation default attribute:"); + + indent(); + annotationDefaultAttribute.defaultValueAccept(clazz, this); + outdent(); + } + + + // Implementations for BootstrapMethodInfoVisitor. + + public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo) + { + println(visitorInfo(bootstrapMethodInfo) + + " BootstrapMethodInfo (argument count = " + + bootstrapMethodInfo.u2methodArgumentCount+ "):"); + + indent(); + clazz.constantPoolEntryAccept(bootstrapMethodInfo.u2methodHandleIndex, this); + bootstrapMethodInfo.methodArgumentsAccept(clazz, this); + outdent(); + } + + + // Implementations for InnerClassesInfoVisitor. + + public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) + { + println(visitorInfo(innerClassesInfo) + + " InnerClassesInfo:"); + + indent(); + println("Access flags: 0x" + Integer.toHexString(innerClassesInfo.u2innerClassAccessFlags) + " = " + + ClassUtil.externalClassAccessFlags(innerClassesInfo.u2innerClassAccessFlags)); + innerClassesInfo.innerClassConstantAccept(clazz, this); + innerClassesInfo.outerClassConstantAccept(clazz, this); + innerClassesInfo.innerNameConstantAccept(clazz, this); + outdent(); + } + + + // Implementations for InstructionVisitor. + + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) + { + println(instruction.toString(offset)); + } + + + public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) + { + println(constantInstruction.toString(offset)); + + indent(); + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + outdent(); + } + + + public void visitTableSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction) + { + println(tableSwitchInstruction.toString(offset)); + + indent(); + + int[] jumpOffsets = tableSwitchInstruction.jumpOffsets; + + for (int index = 0; index < jumpOffsets.length; index++) + { + int jumpOffset = jumpOffsets[index]; + println(Integer.toString(tableSwitchInstruction.lowCase + index) + ": offset = " + jumpOffset + ", target = " + (offset + jumpOffset)); + } + + int defaultOffset = tableSwitchInstruction.defaultOffset; + println("default: offset = " + defaultOffset + ", target = "+ (offset + defaultOffset)); + + outdent(); + } + + + public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction) + { + println(lookUpSwitchInstruction.toString(offset)); + + indent(); + + int[] cases = lookUpSwitchInstruction.cases; + int[] jumpOffsets = lookUpSwitchInstruction.jumpOffsets; + + for (int index = 0; index < jumpOffsets.length; index++) + { + int jumpOffset = jumpOffsets[index]; + println(Integer.toString(cases[index]) + ": offset = " + jumpOffset + ", target = " + (offset + jumpOffset)); + } + + int defaultOffset = lookUpSwitchInstruction.defaultOffset; + println("default: offset = " + defaultOffset + ", target = "+ (offset + defaultOffset)); + + outdent(); + } + + + // Implementations for ExceptionInfoVisitor. + + public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) + { + println(visitorInfo(exceptionInfo) + + " ExceptionInfo (" + + exceptionInfo.u2startPC + " -> " + + exceptionInfo.u2endPC + ": " + + exceptionInfo.u2handlerPC + "):"); + + if (exceptionInfo.u2catchType != 0) + { + clazz.constantPoolEntryAccept(exceptionInfo.u2catchType, this); + } + } + + + // Implementations for StackMapFrameVisitor. + + public void visitSameZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameZeroFrame sameZeroFrame) + { + println(visitorInfo(sameZeroFrame) + + " [" + offset + "]" + + " Var: ..., Stack: (empty)"); + } + + + public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame) + { + print(visitorInfo(sameOneFrame) + + " [" + offset + "]" + + " Var: ..., Stack: "); + + sameOneFrame.stackItemAccept(clazz, method, codeAttribute, offset, this); + + println(); + } + + + public void visitLessZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LessZeroFrame lessZeroFrame) + { + println(visitorInfo(lessZeroFrame) + + " [" + offset + "]" + + " Var: -" + lessZeroFrame.choppedVariablesCount + + ", Stack: (empty)"); + } + + + public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame) + { + print(visitorInfo(moreZeroFrame) + + " [" + offset + "]" + + " Var: ..."); + + moreZeroFrame.additionalVariablesAccept(clazz, method, codeAttribute, offset, this); + + ps.println(", Stack: (empty)"); + } + + + public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame) + { + print(visitorInfo(fullFrame) + + " [" + offset + "]" + + " Var: "); + + fullFrame.variablesAccept(clazz, method, codeAttribute, offset, this); + + ps.print(", Stack: "); + + fullFrame.stackAccept(clazz, method, codeAttribute, offset, this); + + println(); + } + + + // Implementations for VerificationTypeVisitor. + + public void visitIntegerType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, IntegerType integerType) + { + ps.print("[i]"); + } + + + public void visitFloatType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FloatType floatType) + { + ps.print("[f]"); + } + + + public void visitLongType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LongType longType) + { + ps.print("[l]"); + } + + + public void visitDoubleType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, DoubleType doubleType) + { + ps.print("[d]"); + } + + + public void visitTopType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TopType topType) + { + ps.print("[T]"); + } + + + public void visitObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType) + { + ps.print("[a:" + clazz.getClassName(objectType.u2classIndex) + "]"); + } + + + public void visitNullType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, NullType nullType) + { + ps.print("[n]"); + } + + + public void visitUninitializedType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, UninitializedType uninitializedType) + { + ps.print("[u:" + uninitializedType.u2newInstructionOffset + "]"); + } + + + public void visitUninitializedThisType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, UninitializedThisType uninitializedThisType) + { + ps.print("[u:this]"); + } + + + // Implementations for LineNumberInfoVisitor. + + public void visitLineNumberInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberInfo lineNumberInfo) + { + println("[" + lineNumberInfo.u2startPC + "] -> line " + + lineNumberInfo.u2lineNumber + + (lineNumberInfo.getSource() == null ? "" : " [" + lineNumberInfo.getSource() + "]")); + } + + + // Implementations for ParameterInfoVisitor. + + public void visitParameterInfo(Clazz clazz, Method method, int parameterIndex, ParameterInfo parameterInfo) + { + println("p" + parameterIndex + ": access flags: 0x" + Integer.toHexString(parameterInfo.u2accessFlags) + " = " + + ClassUtil.externalParameterAccessFlags(parameterInfo.u2accessFlags) + + (parameterInfo.u2nameIndex == 0 ? "" : " [" + parameterInfo.getName(clazz) + "]")); + } + + + // Implementations for LocalVariableInfoVisitor. + + public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) + { + println("v" + localVariableInfo.u2index + ": " + + localVariableInfo.u2startPC + " -> " + + (localVariableInfo.u2startPC + localVariableInfo.u2length) + " [" + + localVariableInfo.getDescriptor(clazz) + " " + + localVariableInfo.getName(clazz) + "]"); + } + + + // Implementations for LocalVariableTypeInfoVisitor. + + public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo) + { + println("v" + localVariableTypeInfo.u2index + ": " + + localVariableTypeInfo.u2startPC + " -> " + + (localVariableTypeInfo.u2startPC + localVariableTypeInfo.u2length) + " [" + + localVariableTypeInfo.getSignature(clazz) + " " + + localVariableTypeInfo.getName(clazz) + "]"); + } + + + // Implementations for AnnotationVisitor. + + public void visitAnnotation(Clazz clazz, Annotation annotation) + { + println(visitorInfo(annotation) + + " Annotation [" + annotation.getType(clazz) + "]:"); + + indent(); + annotation.elementValuesAccept(clazz, this); + outdent(); + } + + + // Implementations for TypeAnnotationVisitor. + + public void visitTypeAnnotation(Clazz clazz, TypeAnnotation typeAnnotation) + { + println(visitorInfo(typeAnnotation) + + " Type annotation [" + typeAnnotation.getType(clazz) + "]:"); + + indent(); + typeAnnotation.targetInfoAccept(clazz, this); + + println("Type path (count = " + typeAnnotation.typePath.length + "):"); + indent(); + typeAnnotation.typePathInfosAccept(clazz, this); + outdent(); + + typeAnnotation.elementValuesAccept(clazz, this); + + outdent(); + } + + + // Implementations for TargetInfoVisitor. + + public void visitTypeParameterTargetInfo(Clazz clazz, TypeAnnotation typeAnnotation, TypeParameterTargetInfo typeParameterTargetInfo) + { + println("Target (type = 0x" + Integer.toHexString(typeParameterTargetInfo.u1targetType) + "): Parameter #" + + typeParameterTargetInfo.u1typeParameterIndex); + } + + + public void visitSuperTypeTargetInfo(Clazz clazz, TypeAnnotation typeAnnotation, SuperTypeTargetInfo superTypeTargetInfo) + { + println("Target (type = 0x" + Integer.toHexString(superTypeTargetInfo.u1targetType) + "): " + + (superTypeTargetInfo.u2superTypeIndex == 0xffff ? + "super class" : + "interface #" + superTypeTargetInfo.u2superTypeIndex)); + } + + + public void visitTypeParameterBoundTargetInfo(Clazz clazz, TypeAnnotation typeAnnotation, TypeParameterBoundTargetInfo typeParameterBoundTargetInfo) + { + println("Target (type = 0x" + Integer.toHexString(typeParameterBoundTargetInfo.u1targetType) + "): parameter #" + + typeParameterBoundTargetInfo.u1typeParameterIndex + ", bound #" + typeParameterBoundTargetInfo.u1boundIndex); + } + + + public void visitEmptyTargetInfo(Clazz clazz, Member member, TypeAnnotation typeAnnotation, EmptyTargetInfo emptyTargetInfo) + { + println("Target (type = 0x" + Integer.toHexString(emptyTargetInfo.u1targetType) + ")"); + } + + + public void visitFormalParameterTargetInfo(Clazz clazz, Method method, TypeAnnotation typeAnnotation, FormalParameterTargetInfo formalParameterTargetInfo) + { + println("Target (type = 0x" + Integer.toHexString(formalParameterTargetInfo.u1targetType) + "): formal parameter #" + + formalParameterTargetInfo.u1formalParameterIndex); + } + + + public void visitThrowsTargetInfo(Clazz clazz, Method method, TypeAnnotation typeAnnotation, ThrowsTargetInfo throwsTargetInfo) + { + println("Target (type = 0x" + Integer.toHexString(throwsTargetInfo.u1targetType) + "): throws #" + + throwsTargetInfo.u2throwsTypeIndex); + } + + + public void visitLocalVariableTargetInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, LocalVariableTargetInfo localVariableTargetInfo) + { + println("Target (type = 0x" + Integer.toHexString(localVariableTargetInfo.u1targetType) + "): local variables (count = " + + localVariableTargetInfo.u2tableLength + ")"); + + indent(); + localVariableTargetInfo.targetElementsAccept(clazz, method, codeAttribute, typeAnnotation, this); + outdent(); + } + + + public void visitCatchTargetInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, CatchTargetInfo catchTargetInfo) + { + println("Target (type = 0x" + Integer.toHexString(catchTargetInfo.u1targetType) + "): catch #" + + catchTargetInfo.u2exceptionTableIndex); + } + + + public void visitOffsetTargetInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, OffsetTargetInfo offsetTargetInfo) + { + println("Target (type = 0x" + Integer.toHexString(offsetTargetInfo.u1targetType) + "): offset " + + offsetTargetInfo.u2offset); + } + + + public void visitTypeArgumentTargetInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, TypeArgumentTargetInfo typeArgumentTargetInfo) + { + println("Target (type = 0x" + Integer.toHexString(typeArgumentTargetInfo.u1targetType) + "): offset " + + typeArgumentTargetInfo.u2offset + ", type argument " + + typeArgumentTargetInfo.u1typeArgumentIndex); + } + + + // Implementations for TypePathInfoVisitor. + + public void visitTypePathInfo(Clazz clazz, TypeAnnotation typeAnnotation, TypePathInfo typePathInfo) + { + println("kind = " + + typePathInfo.u1typePathKind + ", argument index = " + + typePathInfo.u1typeArgumentIndex); + } + + + // Implementations for LocalVariableTargetElementVisitor. + + public void visitLocalVariableTargetElement(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, LocalVariableTargetInfo localVariableTargetInfo, LocalVariableTargetElement localVariableTargetElement) + { + println("v" + + localVariableTargetElement.u2index + ": " + + localVariableTargetElement.u2startPC + " -> " + + (localVariableTargetElement.u2startPC + localVariableTargetElement.u2length)); + } + + + // Implementations for ElementValueVisitor. + + public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue) + { + println(visitorInfo(constantElementValue) + + " Constant element value [" + + (constantElementValue.u2elementNameIndex == 0 ? "(default)" : + constantElementValue.getMethodName(clazz)) + " '" + + constantElementValue.u1tag + "']"); + + indent(); + clazz.constantPoolEntryAccept(constantElementValue.u2constantValueIndex, this); + outdent(); + } + + + public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue) + { + println(visitorInfo(enumConstantElementValue) + + " Enum constant element value [" + + (enumConstantElementValue.u2elementNameIndex == 0 ? "(default)" : + enumConstantElementValue.getMethodName(clazz)) + ", " + + enumConstantElementValue.getTypeName(clazz) + ", " + + enumConstantElementValue.getConstantName(clazz) + "]"); + } + + + public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue) + { + println(visitorInfo(classElementValue) + + " Class element value [" + + (classElementValue.u2elementNameIndex == 0 ? "(default)" : + classElementValue.getMethodName(clazz)) + ", " + + classElementValue.getClassName(clazz) + "]"); + } + + + public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue) + { + println(visitorInfo(annotationElementValue) + + " Annotation element value [" + + (annotationElementValue.u2elementNameIndex == 0 ? "(default)" : + annotationElementValue.getMethodName(clazz)) + "]:"); + + indent(); + annotationElementValue.annotationAccept(clazz, this); + outdent(); + } + + + public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue) + { + println(visitorInfo(arrayElementValue) + + " Array element value [" + + (arrayElementValue.u2elementNameIndex == 0 ? "(default)" : + arrayElementValue.getMethodName(clazz)) + "]:"); + + indent(); + arrayElementValue.elementValuesAccept(clazz, annotation, this); + outdent(); + } + + + // Small utility methods. + + private void indent() + { + indentation++; + } + + private void outdent() + { + indentation--; + } + + private void println(String string) + { + print(string); + println(); + + } + + private void print(String string) + { + for (int index = 0; index < indentation; index++) + { + ps.print(INDENTATION); + } + + ps.print(string); + } + + private void println() + { + ps.println(); + } + + + private String visitorInfo(VisitorAccepter visitorAccepter) + { + return visitorAccepter.getVisitorInfo() == null ? "-" : "+"; + } +} |