1/* 2 * ProGuard -- shrinking, optimization, obfuscation, and preverification 3 * of Java bytecode. 4 * 5 * Copyright (c) 2002-2014 Eric Lafortune (eric@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 */ 21package proguard.classfile.visitor; 22 23import proguard.classfile.*; 24import proguard.classfile.attribute.*; 25import proguard.classfile.attribute.annotation.*; 26import proguard.classfile.attribute.annotation.target.*; 27import proguard.classfile.attribute.annotation.target.visitor.*; 28import proguard.classfile.attribute.annotation.visitor.*; 29import proguard.classfile.attribute.preverification.*; 30import proguard.classfile.attribute.preverification.visitor.*; 31import proguard.classfile.attribute.visitor.*; 32import proguard.classfile.constant.*; 33import proguard.classfile.constant.visitor.ConstantVisitor; 34import proguard.classfile.instruction.*; 35import proguard.classfile.instruction.visitor.InstructionVisitor; 36import proguard.classfile.util.*; 37 38import java.io.PrintStream; 39 40 41/** 42 * This <code>ClassVisitor</code> prints out the complete internal 43 * structure of the classes it visits. 44 * 45 * @author Eric Lafortune 46 */ 47public class ClassPrinter 48extends SimplifiedVisitor 49implements ClassVisitor, 50 ConstantVisitor, 51 MemberVisitor, 52 AttributeVisitor, 53 BootstrapMethodInfoVisitor, 54 InnerClassesInfoVisitor, 55 ExceptionInfoVisitor, 56 StackMapFrameVisitor, 57 VerificationTypeVisitor, 58 LineNumberInfoVisitor, 59 ParameterInfoVisitor, 60 LocalVariableInfoVisitor, 61 LocalVariableTypeInfoVisitor, 62 AnnotationVisitor, 63 TypeAnnotationVisitor, 64 TargetInfoVisitor, 65 LocalVariableTargetElementVisitor, 66 TypePathInfoVisitor, 67 ElementValueVisitor, 68 InstructionVisitor 69{ 70 private static final String INDENTATION = " "; 71 72 private final PrintStream ps; 73 74 private int indentation; 75 76 77 /** 78 * Creates a new ClassPrinter that prints to <code>System.out</code>. 79 */ 80 public ClassPrinter() 81 { 82 this(System.out); 83 } 84 85 86 /** 87 * Creates a new ClassPrinter that prints to the given 88 * <code>PrintStream</code>. 89 */ 90 public ClassPrinter(PrintStream printStream) 91 { 92 ps = printStream; 93 } 94 95 96 // Implementations for ClassVisitor. 97 98 public void visitProgramClass(ProgramClass programClass) 99 { 100 println("_____________________________________________________________________"); 101 println(visitorInfo(programClass) + " " + 102 "Program class: " + programClass.getName()); 103 indent(); 104 println("Superclass: " + programClass.getSuperName()); 105 println("Major version: 0x" + Integer.toHexString(ClassUtil.internalMajorClassVersion(programClass.u4version))); 106 println("Minor version: 0x" + Integer.toHexString(ClassUtil.internalMinorClassVersion(programClass.u4version))); 107 println(" = target " + ClassUtil.externalClassVersion(programClass.u4version)); 108 println("Access flags: 0x" + Integer.toHexString(programClass.u2accessFlags)); 109 println(" = " + 110 ((programClass.u2accessFlags & ClassConstants.ACC_ANNOTATTION) != 0 ? "@ " : "") + 111 ClassUtil.externalClassAccessFlags(programClass.u2accessFlags) + 112 ((programClass.u2accessFlags & ClassConstants.ACC_ENUM) != 0 ? "enum " : 113 (programClass.u2accessFlags & ClassConstants.ACC_INTERFACE) == 0 ? "class " : 114 "") + 115 ClassUtil.externalClassName(programClass.getName()) + 116 (programClass.u2superClass == 0 ? "" : " extends " + 117 ClassUtil.externalClassName(programClass.getSuperName()))); 118 outdent(); 119 println(); 120 121 println("Interfaces (count = " + programClass.u2interfacesCount + "):"); 122 indent(); 123 programClass.interfaceConstantsAccept(this); 124 outdent(); 125 println(); 126 127 println("Constant Pool (count = " + programClass.u2constantPoolCount + "):"); 128 indent(); 129 programClass.constantPoolEntriesAccept(this); 130 outdent(); 131 println(); 132 133 println("Fields (count = " + programClass.u2fieldsCount + "):"); 134 indent(); 135 programClass.fieldsAccept(this); 136 outdent(); 137 println(); 138 139 println("Methods (count = " + programClass.u2methodsCount + "):"); 140 indent(); 141 programClass.methodsAccept(this); 142 outdent(); 143 println(); 144 145 println("Class file attributes (count = " + programClass.u2attributesCount + "):"); 146 indent(); 147 programClass.attributesAccept(this); 148 outdent(); 149 println(); 150 } 151 152 153 public void visitLibraryClass(LibraryClass libraryClass) 154 { 155 println("_____________________________________________________________________"); 156 println(visitorInfo(libraryClass) + " " + 157 "Library class: " + libraryClass.getName()); 158 indent(); 159 println("Superclass: " + libraryClass.getSuperName()); 160 println("Access flags: 0x" + Integer.toHexString(libraryClass.u2accessFlags)); 161 println(" = " + 162 ((libraryClass.u2accessFlags & ClassConstants.ACC_ANNOTATTION) != 0 ? "@ " : "") + 163 ClassUtil.externalClassAccessFlags(libraryClass.u2accessFlags) + 164 ((libraryClass.u2accessFlags & ClassConstants.ACC_ENUM) != 0 ? "enum " : 165 (libraryClass.u2accessFlags & ClassConstants.ACC_INTERFACE) == 0 ? "class " : 166 "") + 167 ClassUtil.externalClassName(libraryClass.getName()) + 168 (libraryClass.getSuperName() == null ? "" : " extends " + 169 ClassUtil.externalClassName(libraryClass.getSuperName()))); 170 outdent(); 171 println(); 172 173 println("Interfaces (count = " + libraryClass.interfaceClasses.length + "):"); 174 for (int index = 0; index < libraryClass.interfaceClasses.length; index++) 175 { 176 Clazz interfaceClass = libraryClass.interfaceClasses[index]; 177 if (interfaceClass != null) 178 { 179 println(" + " + interfaceClass.getName()); 180 } 181 } 182 183 println("Fields (count = " + libraryClass.fields.length + "):"); 184 libraryClass.fieldsAccept(this); 185 186 println("Methods (count = " + libraryClass.methods.length + "):"); 187 libraryClass.methodsAccept(this); 188 } 189 190 191 // Implementations for ConstantVisitor. 192 193 public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant) 194 { 195 println(visitorInfo(integerConstant) + " Integer [" + 196 integerConstant.getValue() + "]"); 197 } 198 199 200 public void visitLongConstant(Clazz clazz, LongConstant longConstant) 201 { 202 println(visitorInfo(longConstant) + " Long [" + 203 longConstant.getValue() + "]"); 204 } 205 206 207 public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant) 208 { 209 println(visitorInfo(floatConstant) + " Float [" + 210 floatConstant.getValue() + "]"); 211 } 212 213 214 public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant) 215 { 216 println(visitorInfo(doubleConstant) + " Double [" + 217 doubleConstant.getValue() + "]"); 218 } 219 220 221 public void visitStringConstant(Clazz clazz, StringConstant stringConstant) 222 { 223 println(visitorInfo(stringConstant) + " String [" + 224 stringConstant.getString(clazz) + "]"); 225 } 226 227 228 public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant) 229 { 230 println(visitorInfo(utf8Constant) + " Utf8 [" + 231 utf8Constant.getString() + "]"); 232 } 233 234 235 public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) 236 { 237 println(visitorInfo(invokeDynamicConstant) + " InvokeDynamic [bootstrap method index = " + invokeDynamicConstant.u2bootstrapMethodAttributeIndex + "]:"); 238 239 indent(); 240 clazz.constantPoolEntryAccept(invokeDynamicConstant.u2nameAndTypeIndex, this); 241 outdent(); 242 } 243 244 245 public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) 246 { 247 println(visitorInfo(methodHandleConstant) + " MethodHandle [kind = " + methodHandleConstant.u1referenceKind + "]:"); 248 249 indent(); 250 clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this); 251 outdent(); 252 } 253 254 255 public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) 256 { 257 println(visitorInfo(fieldrefConstant) + " Fieldref [" + 258 clazz.getClassName(fieldrefConstant.u2classIndex) + "." + 259 clazz.getName(fieldrefConstant.u2nameAndTypeIndex) + " " + 260 clazz.getType(fieldrefConstant.u2nameAndTypeIndex) + "]"); 261 } 262 263 264 public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant) 265 { 266 println(visitorInfo(interfaceMethodrefConstant) + " InterfaceMethodref [" + 267 clazz.getClassName(interfaceMethodrefConstant.u2classIndex) + "." + 268 clazz.getName(interfaceMethodrefConstant.u2nameAndTypeIndex) + " " + 269 clazz.getType(interfaceMethodrefConstant.u2nameAndTypeIndex) + "]"); 270 } 271 272 273 public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant) 274 { 275 println(visitorInfo(methodrefConstant) + " Methodref [" + 276 clazz.getClassName(methodrefConstant.u2classIndex) + "." + 277 clazz.getName(methodrefConstant.u2nameAndTypeIndex) + " " + 278 clazz.getType(methodrefConstant.u2nameAndTypeIndex) + "]"); 279 } 280 281 282 public void visitClassConstant(Clazz clazz, ClassConstant classConstant) 283 { 284 println(visitorInfo(classConstant) + " Class [" + 285 classConstant.getName(clazz) + "]"); 286 } 287 288 289 public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) 290 { 291 println(visitorInfo(methodTypeConstant) + " MethodType [" + 292 methodTypeConstant.getType(clazz) + "]"); 293 } 294 295 296 public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) 297 { 298 println(visitorInfo(nameAndTypeConstant) + " NameAndType [" + 299 nameAndTypeConstant.getName(clazz) + " " + 300 nameAndTypeConstant.getType(clazz) + "]"); 301 } 302 303 304 // Implementations for MemberVisitor. 305 306 public void visitProgramField(ProgramClass programClass, ProgramField programField) 307 { 308 println(visitorInfo(programField) + " " + 309 "Field: " + 310 programField.getName(programClass) + " " + 311 programField.getDescriptor(programClass)); 312 313 indent(); 314 println("Access flags: 0x" + Integer.toHexString(programField.u2accessFlags)); 315 println(" = " + 316 ClassUtil.externalFullFieldDescription(programField.u2accessFlags, 317 programField.getName(programClass), 318 programField.getDescriptor(programClass))); 319 320 visitMember(programClass, programField); 321 outdent(); 322 } 323 324 325 public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) 326 { 327 println(visitorInfo(programMethod) + " " + 328 "Method: " + 329 programMethod.getName(programClass) + 330 programMethod.getDescriptor(programClass)); 331 332 indent(); 333 println("Access flags: 0x" + Integer.toHexString(programMethod.u2accessFlags)); 334 println(" = " + 335 ClassUtil.externalFullMethodDescription(programClass.getName(), 336 programMethod.u2accessFlags, 337 programMethod.getName(programClass), 338 programMethod.getDescriptor(programClass))); 339 340 visitMember(programClass, programMethod); 341 outdent(); 342 } 343 344 345 private void visitMember(ProgramClass programClass, ProgramMember programMember) 346 { 347 if (programMember.u2attributesCount > 0) 348 { 349 println("Class member attributes (count = " + programMember.u2attributesCount + "):"); 350 programMember.attributesAccept(programClass, this); 351 } 352 } 353 354 355 public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField) 356 { 357 println(visitorInfo(libraryField) + " " + 358 "Field: " + 359 libraryField.getName(libraryClass) + " " + 360 libraryField.getDescriptor(libraryClass)); 361 362 indent(); 363 println("Access flags: 0x" + Integer.toHexString(libraryField.u2accessFlags)); 364 println(" = " + 365 ClassUtil.externalFullFieldDescription(libraryField.u2accessFlags, 366 libraryField.getName(libraryClass), 367 libraryField.getDescriptor(libraryClass))); 368 outdent(); 369 } 370 371 372 public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) 373 { 374 println(visitorInfo(libraryMethod) + " " + 375 "Method: " + 376 libraryMethod.getName(libraryClass) + " " + 377 libraryMethod.getDescriptor(libraryClass)); 378 379 indent(); 380 println("Access flags: 0x" + Integer.toHexString(libraryMethod.u2accessFlags)); 381 println(" = " + 382 ClassUtil.externalFullMethodDescription(libraryClass.getName(), 383 libraryMethod.u2accessFlags, 384 libraryMethod.getName(libraryClass), 385 libraryMethod.getDescriptor(libraryClass))); 386 outdent(); 387 } 388 389 390 // Implementations for AttributeVisitor. 391 // Note that attributes are typically only referenced once, so we don't 392 // test if they are marked already. 393 394 public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute) 395 { 396 println(visitorInfo(unknownAttribute) + 397 " Unknown attribute (" + unknownAttribute.getAttributeName(clazz) + ")"); 398 } 399 400 401 public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) 402 { 403 println(visitorInfo(bootstrapMethodsAttribute) + 404 " Bootstrap methods attribute (count = " + bootstrapMethodsAttribute.u2bootstrapMethodsCount + "):"); 405 406 indent(); 407 bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this); 408 outdent(); 409 } 410 411 412 public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) 413 { 414 println(visitorInfo(sourceFileAttribute) + 415 " Source file attribute:"); 416 417 indent(); 418 clazz.constantPoolEntryAccept(sourceFileAttribute.u2sourceFileIndex, this); 419 outdent(); 420 } 421 422 423 public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute) 424 { 425 println(visitorInfo(sourceDirAttribute) + 426 " Source dir attribute:"); 427 428 indent(); 429 clazz.constantPoolEntryAccept(sourceDirAttribute.u2sourceDirIndex, this); 430 outdent(); 431 } 432 433 434 public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute) 435 { 436 println(visitorInfo(innerClassesAttribute) + 437 " Inner classes attribute (count = " + innerClassesAttribute.u2classesCount + ")"); 438 439 indent(); 440 innerClassesAttribute.innerClassEntriesAccept(clazz, this); 441 outdent(); 442 } 443 444 445 public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute) 446 { 447 println(visitorInfo(enclosingMethodAttribute) + 448 " Enclosing method attribute:"); 449 450 indent(); 451 clazz.constantPoolEntryAccept(enclosingMethodAttribute.u2classIndex, this); 452 453 if (enclosingMethodAttribute.u2nameAndTypeIndex != 0) 454 { 455 clazz.constantPoolEntryAccept(enclosingMethodAttribute.u2nameAndTypeIndex, this); 456 } 457 outdent(); 458 } 459 460 461 public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute) 462 { 463 println(visitorInfo(deprecatedAttribute) + 464 " Deprecated attribute"); 465 } 466 467 468 public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute) 469 { 470 println(visitorInfo(syntheticAttribute) + 471 " Synthetic attribute"); 472 } 473 474 475 public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute) 476 { 477 println(visitorInfo(signatureAttribute) + 478 " Signature attribute:"); 479 480 indent(); 481 clazz.constantPoolEntryAccept(signatureAttribute.u2signatureIndex, this); 482 outdent(); 483 } 484 485 486 public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute) 487 { 488 println(visitorInfo(constantValueAttribute) + 489 " Constant value attribute:"); 490 491 clazz.constantPoolEntryAccept(constantValueAttribute.u2constantValueIndex, this); 492 } 493 494 495 public void visitMethodParametersAttribute(Clazz clazz, Method method, MethodParametersAttribute methodParametersAttribute) 496 { 497 println(visitorInfo(methodParametersAttribute) + 498 " Method parameters attribute (count = " + methodParametersAttribute.u1parametersCount + ")"); 499 500 indent(); 501 methodParametersAttribute.parametersAccept(clazz, method, this); 502 outdent(); 503 } 504 505 506 public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute) 507 { 508 println(visitorInfo(exceptionsAttribute) + 509 " Exceptions attribute (count = " + exceptionsAttribute.u2exceptionIndexTableLength + ")"); 510 511 indent(); 512 exceptionsAttribute.exceptionEntriesAccept((ProgramClass)clazz, this); 513 outdent(); 514 } 515 516 517 public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) 518 { 519 println(visitorInfo(codeAttribute) + 520 " Code attribute instructions (code length = "+ codeAttribute.u4codeLength + 521 ", locals = "+ codeAttribute.u2maxLocals + 522 ", stack = "+ codeAttribute.u2maxStack + "):"); 523 524 indent(); 525 526 codeAttribute.instructionsAccept(clazz, method, this); 527 528 println("Code attribute exceptions (count = " + 529 codeAttribute.u2exceptionTableLength + "):"); 530 531 codeAttribute.exceptionsAccept(clazz, method, this); 532 533 println("Code attribute attributes (attribute count = " + 534 codeAttribute.u2attributesCount + "):"); 535 536 codeAttribute.attributesAccept(clazz, method, this); 537 538 outdent(); 539 } 540 541 542 public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute) 543 { 544 println(visitorInfo(codeAttribute) + 545 " Stack map attribute (count = "+ 546 stackMapAttribute.u2stackMapFramesCount + "):"); 547 548 indent(); 549 stackMapAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this); 550 outdent(); 551 } 552 553 554 public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute) 555 { 556 println(visitorInfo(codeAttribute) + 557 " Stack map table attribute (count = "+ 558 stackMapTableAttribute.u2stackMapFramesCount + "):"); 559 560 indent(); 561 stackMapTableAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this); 562 outdent(); 563 } 564 565 566 public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute) 567 { 568 println(visitorInfo(lineNumberTableAttribute) + 569 " Line number table attribute (count = " + 570 lineNumberTableAttribute.u2lineNumberTableLength + ")"); 571 572 indent(); 573 lineNumberTableAttribute.lineNumbersAccept(clazz, method, codeAttribute, this); 574 outdent(); 575 } 576 577 578 public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute) 579 { 580 println(visitorInfo(localVariableTableAttribute) + 581 " Local variable table attribute (count = " + 582 localVariableTableAttribute.u2localVariableTableLength + ")"); 583 584 indent(); 585 localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); 586 outdent(); 587 } 588 589 590 public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute) 591 { 592 println(visitorInfo(localVariableTypeTableAttribute) + 593 " Local variable type table attribute (count = "+ 594 localVariableTypeTableAttribute.u2localVariableTypeTableLength + ")"); 595 596 indent(); 597 localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); 598 outdent(); 599 } 600 601 602 public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute) 603 { 604 println(visitorInfo(runtimeVisibleAnnotationsAttribute) + 605 " Runtime visible annotations attribute:"); 606 607 indent(); 608 runtimeVisibleAnnotationsAttribute.annotationsAccept(clazz, this); 609 outdent(); 610 } 611 612 613 public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute) 614 { 615 println(visitorInfo(runtimeInvisibleAnnotationsAttribute) + 616 " Runtime invisible annotations attribute:"); 617 618 indent(); 619 runtimeInvisibleAnnotationsAttribute.annotationsAccept(clazz, this); 620 outdent(); 621 } 622 623 624 public void visitRuntimeVisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute) 625 { 626 println(visitorInfo(runtimeVisibleParameterAnnotationsAttribute) + 627 " Runtime visible parameter annotations attribute (parameter count = " + runtimeVisibleParameterAnnotationsAttribute.u1parametersCount + "):"); 628 629 indent(); 630 runtimeVisibleParameterAnnotationsAttribute.annotationsAccept(clazz, method, this); 631 outdent(); 632 } 633 634 635 public void visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute) 636 { 637 println(visitorInfo(runtimeInvisibleParameterAnnotationsAttribute) + 638 " Runtime invisible parameter annotations attribute (parameter count = " + runtimeInvisibleParameterAnnotationsAttribute.u1parametersCount + "):"); 639 640 indent(); 641 runtimeInvisibleParameterAnnotationsAttribute.annotationsAccept(clazz, method, this); 642 outdent(); 643 } 644 645 646 public void visitRuntimeVisibleTypeAnnotationsAttribute(Clazz clazz, RuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute) 647 { 648 println(visitorInfo(runtimeVisibleTypeAnnotationsAttribute) + 649 " Runtime visible type annotations attribute"); 650 651 indent(); 652 runtimeVisibleTypeAnnotationsAttribute.typeAnnotationsAccept(clazz, this); 653 outdent(); 654 } 655 656 657 public void visitRuntimeInvisibleTypeAnnotationsAttribute(Clazz clazz, RuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute) 658 { 659 println(visitorInfo(runtimeInvisibleTypeAnnotationsAttribute) + 660 " Runtime invisible type annotations attribute"); 661 662 indent(); 663 runtimeInvisibleTypeAnnotationsAttribute.typeAnnotationsAccept(clazz, this); 664 outdent(); 665 } 666 667 668 public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute) 669 { 670 println(visitorInfo(annotationDefaultAttribute) + 671 " Annotation default attribute:"); 672 673 indent(); 674 annotationDefaultAttribute.defaultValueAccept(clazz, this); 675 outdent(); 676 } 677 678 679 // Implementations for BootstrapMethodInfoVisitor. 680 681 public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo) 682 { 683 println(visitorInfo(bootstrapMethodInfo) + 684 " BootstrapMethodInfo (argument count = " + 685 bootstrapMethodInfo.u2methodArgumentCount+ "):"); 686 687 indent(); 688 clazz.constantPoolEntryAccept(bootstrapMethodInfo.u2methodHandleIndex, this); 689 bootstrapMethodInfo.methodArgumentsAccept(clazz, this); 690 outdent(); 691 } 692 693 694 // Implementations for InnerClassesInfoVisitor. 695 696 public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) 697 { 698 println(visitorInfo(innerClassesInfo) + 699 " InnerClassesInfo:"); 700 701 indent(); 702 println("Access flags: 0x" + Integer.toHexString(innerClassesInfo.u2innerClassAccessFlags) + " = " + 703 ClassUtil.externalClassAccessFlags(innerClassesInfo.u2innerClassAccessFlags)); 704 innerClassesInfo.innerClassConstantAccept(clazz, this); 705 innerClassesInfo.outerClassConstantAccept(clazz, this); 706 innerClassesInfo.innerNameConstantAccept(clazz, this); 707 outdent(); 708 } 709 710 711 // Implementations for InstructionVisitor. 712 713 public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) 714 { 715 println(instruction.toString(offset)); 716 } 717 718 719 public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) 720 { 721 println(constantInstruction.toString(offset)); 722 723 indent(); 724 clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); 725 outdent(); 726 } 727 728 729 public void visitTableSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction) 730 { 731 println(tableSwitchInstruction.toString(offset)); 732 733 indent(); 734 735 int[] jumpOffsets = tableSwitchInstruction.jumpOffsets; 736 737 for (int index = 0; index < jumpOffsets.length; index++) 738 { 739 int jumpOffset = jumpOffsets[index]; 740 println(Integer.toString(tableSwitchInstruction.lowCase + index) + ": offset = " + jumpOffset + ", target = " + (offset + jumpOffset)); 741 } 742 743 int defaultOffset = tableSwitchInstruction.defaultOffset; 744 println("default: offset = " + defaultOffset + ", target = "+ (offset + defaultOffset)); 745 746 outdent(); 747 } 748 749 750 public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction) 751 { 752 println(lookUpSwitchInstruction.toString(offset)); 753 754 indent(); 755 756 int[] cases = lookUpSwitchInstruction.cases; 757 int[] jumpOffsets = lookUpSwitchInstruction.jumpOffsets; 758 759 for (int index = 0; index < jumpOffsets.length; index++) 760 { 761 int jumpOffset = jumpOffsets[index]; 762 println(Integer.toString(cases[index]) + ": offset = " + jumpOffset + ", target = " + (offset + jumpOffset)); 763 } 764 765 int defaultOffset = lookUpSwitchInstruction.defaultOffset; 766 println("default: offset = " + defaultOffset + ", target = "+ (offset + defaultOffset)); 767 768 outdent(); 769 } 770 771 772 // Implementations for ExceptionInfoVisitor. 773 774 public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) 775 { 776 println(visitorInfo(exceptionInfo) + 777 " ExceptionInfo (" + 778 exceptionInfo.u2startPC + " -> " + 779 exceptionInfo.u2endPC + ": " + 780 exceptionInfo.u2handlerPC + "):"); 781 782 if (exceptionInfo.u2catchType != 0) 783 { 784 clazz.constantPoolEntryAccept(exceptionInfo.u2catchType, this); 785 } 786 } 787 788 789 // Implementations for StackMapFrameVisitor. 790 791 public void visitSameZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameZeroFrame sameZeroFrame) 792 { 793 println(visitorInfo(sameZeroFrame) + 794 " [" + offset + "]" + 795 " Var: ..., Stack: (empty)"); 796 } 797 798 799 public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame) 800 { 801 print(visitorInfo(sameOneFrame) + 802 " [" + offset + "]" + 803 " Var: ..., Stack: "); 804 805 sameOneFrame.stackItemAccept(clazz, method, codeAttribute, offset, this); 806 807 println(); 808 } 809 810 811 public void visitLessZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LessZeroFrame lessZeroFrame) 812 { 813 println(visitorInfo(lessZeroFrame) + 814 " [" + offset + "]" + 815 " Var: -" + lessZeroFrame.choppedVariablesCount + 816 ", Stack: (empty)"); 817 } 818 819 820 public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame) 821 { 822 print(visitorInfo(moreZeroFrame) + 823 " [" + offset + "]" + 824 " Var: ..."); 825 826 moreZeroFrame.additionalVariablesAccept(clazz, method, codeAttribute, offset, this); 827 828 ps.println(", Stack: (empty)"); 829 } 830 831 832 public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame) 833 { 834 print(visitorInfo(fullFrame) + 835 " [" + offset + "]" + 836 " Var: "); 837 838 fullFrame.variablesAccept(clazz, method, codeAttribute, offset, this); 839 840 ps.print(", Stack: "); 841 842 fullFrame.stackAccept(clazz, method, codeAttribute, offset, this); 843 844 println(); 845 } 846 847 848 // Implementations for VerificationTypeVisitor. 849 850 public void visitIntegerType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, IntegerType integerType) 851 { 852 ps.print("[i]"); 853 } 854 855 856 public void visitFloatType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FloatType floatType) 857 { 858 ps.print("[f]"); 859 } 860 861 862 public void visitLongType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LongType longType) 863 { 864 ps.print("[l]"); 865 } 866 867 868 public void visitDoubleType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, DoubleType doubleType) 869 { 870 ps.print("[d]"); 871 } 872 873 874 public void visitTopType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TopType topType) 875 { 876 ps.print("[T]"); 877 } 878 879 880 public void visitObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType) 881 { 882 ps.print("[a:" + clazz.getClassName(objectType.u2classIndex) + "]"); 883 } 884 885 886 public void visitNullType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, NullType nullType) 887 { 888 ps.print("[n]"); 889 } 890 891 892 public void visitUninitializedType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, UninitializedType uninitializedType) 893 { 894 ps.print("[u:" + uninitializedType.u2newInstructionOffset + "]"); 895 } 896 897 898 public void visitUninitializedThisType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, UninitializedThisType uninitializedThisType) 899 { 900 ps.print("[u:this]"); 901 } 902 903 904 // Implementations for LineNumberInfoVisitor. 905 906 public void visitLineNumberInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberInfo lineNumberInfo) 907 { 908 println("[" + lineNumberInfo.u2startPC + "] -> line " + 909 lineNumberInfo.u2lineNumber); 910 } 911 912 913 // Implementations for ParameterInfoVisitor. 914 915 public void visitParameterInfo(Clazz clazz, Method method, int parameterIndex, ParameterInfo parameterInfo) 916 { 917 println("p" + parameterIndex + ": Access flags: 0x" + Integer.toHexString(parameterInfo.u2accessFlags) + " = " + 918 ClassUtil.externalParameterAccessFlags(parameterInfo.u2accessFlags) + " [" + 919 (parameterInfo.u2nameIndex == 0 ? "" : parameterInfo.getName(clazz)) + "]"); 920 } 921 922 923 // Implementations for LocalVariableInfoVisitor. 924 925 public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) 926 { 927 println("v" + localVariableInfo.u2index + ": " + 928 localVariableInfo.u2startPC + " -> " + 929 (localVariableInfo.u2startPC + localVariableInfo.u2length) + " [" + 930 localVariableInfo.getDescriptor(clazz) + " " + 931 localVariableInfo.getName(clazz) + "]"); 932 } 933 934 935 // Implementations for LocalVariableTypeInfoVisitor. 936 937 public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo) 938 { 939 println("v" + localVariableTypeInfo.u2index + ": " + 940 localVariableTypeInfo.u2startPC + " -> " + 941 (localVariableTypeInfo.u2startPC + localVariableTypeInfo.u2length) + " [" + 942 localVariableTypeInfo.getSignature(clazz) + " " + 943 localVariableTypeInfo.getName(clazz) + "]"); 944 } 945 946 947 // Implementations for AnnotationVisitor. 948 949 public void visitAnnotation(Clazz clazz, Annotation annotation) 950 { 951 println(visitorInfo(annotation) + 952 " Annotation [" + annotation.getType(clazz) + "]:"); 953 954 indent(); 955 annotation.elementValuesAccept(clazz, this); 956 outdent(); 957 } 958 959 960 // Implementations for TypeAnnotationVisitor. 961 962 public void visitTypeAnnotation(Clazz clazz, TypeAnnotation typeAnnotation) 963 { 964 println(visitorInfo(typeAnnotation) + 965 " Type annotation [" + typeAnnotation.getType(clazz) + "]:"); 966 967 indent(); 968 typeAnnotation.targetInfoAccept(clazz, this); 969 970 println("Type path (count = " + typeAnnotation.typePath.length + "):"); 971 indent(); 972 typeAnnotation.typePathInfosAccept(clazz, this); 973 outdent(); 974 975 typeAnnotation.elementValuesAccept(clazz, this); 976 977 outdent(); 978 } 979 980 981 // Implementations for TargetInfoVisitor. 982 983 public void visitTypeParameterTargetInfo(Clazz clazz, TypeAnnotation typeAnnotation, TypeParameterTargetInfo typeParameterTargetInfo) 984 { 985 println("Target (type = 0x" + Integer.toHexString(typeParameterTargetInfo.u1targetType) + "): Parameter #" + 986 typeParameterTargetInfo.u1typeParameterIndex); 987 } 988 989 990 public void visitSuperTypeTargetInfo(Clazz clazz, TypeAnnotation typeAnnotation, SuperTypeTargetInfo superTypeTargetInfo) 991 { 992 println("Target (type = 0x" + Integer.toHexString(superTypeTargetInfo.u1targetType) + "): " + 993 (superTypeTargetInfo.u2superTypeIndex == 0xffff ? 994 "super class" : 995 "interface #" + superTypeTargetInfo.u2superTypeIndex)); 996 } 997 998 999 public void visitTypeParameterBoundTargetInfo(Clazz clazz, TypeAnnotation typeAnnotation, TypeParameterBoundTargetInfo typeParameterBoundTargetInfo) 1000 { 1001 println("Target (type = 0x" + Integer.toHexString(typeParameterBoundTargetInfo.u1targetType) + "): parameter #" + 1002 typeParameterBoundTargetInfo.u1typeParameterIndex + ", bound #" + typeParameterBoundTargetInfo.u1boundIndex); 1003 } 1004 1005 1006 public void visitEmptyTargetInfo(Clazz clazz, Member member, TypeAnnotation typeAnnotation, EmptyTargetInfo emptyTargetInfo) 1007 { 1008 println("Target (type = 0x" + Integer.toHexString(emptyTargetInfo.u1targetType) + ")"); 1009 } 1010 1011 1012 public void visitFormalParameterTargetInfo(Clazz clazz, Method method, TypeAnnotation typeAnnotation, FormalParameterTargetInfo formalParameterTargetInfo) 1013 { 1014 println("Target (type = 0x" + Integer.toHexString(formalParameterTargetInfo.u1targetType) + "): formal parameter #" + 1015 formalParameterTargetInfo.u1formalParameterIndex); 1016 } 1017 1018 1019 public void visitThrowsTargetInfo(Clazz clazz, Method method, TypeAnnotation typeAnnotation, ThrowsTargetInfo throwsTargetInfo) 1020 { 1021 println("Target (type = 0x" + Integer.toHexString(throwsTargetInfo.u1targetType) + "): throws #" + 1022 throwsTargetInfo.u2throwsTypeIndex); 1023 } 1024 1025 1026 public void visitLocalVariableTargetInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, LocalVariableTargetInfo localVariableTargetInfo) 1027 { 1028 println("Target (type = 0x" + Integer.toHexString(localVariableTargetInfo.u1targetType) + "): local variables (count = " + 1029 localVariableTargetInfo.u2tableLength + ")"); 1030 1031 indent(); 1032 localVariableTargetInfo.targetElementsAccept(clazz, method, codeAttribute, typeAnnotation, this); 1033 outdent(); 1034 } 1035 1036 1037 public void visitCatchTargetInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, CatchTargetInfo catchTargetInfo) 1038 { 1039 println("Target (type = 0x" + Integer.toHexString(catchTargetInfo.u1targetType) + "): catch #" + 1040 catchTargetInfo.u2exceptionTableIndex); 1041 } 1042 1043 1044 public void visitOffsetTargetInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, OffsetTargetInfo offsetTargetInfo) 1045 { 1046 println("Target (type = 0x" + Integer.toHexString(offsetTargetInfo.u1targetType) + "): offset " + 1047 offsetTargetInfo.u2offset); 1048 } 1049 1050 1051 public void visitTypeArgumentTargetInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, TypeArgumentTargetInfo typeArgumentTargetInfo) 1052 { 1053 println("Target (type = 0x" + Integer.toHexString(typeArgumentTargetInfo.u1targetType) + "): offset " + 1054 typeArgumentTargetInfo.u2offset + ", type argument " + 1055 typeArgumentTargetInfo.u1typeArgumentIndex); 1056 } 1057 1058 1059 // Implementations for TypePathInfoVisitor. 1060 1061 public void visitTypePathInfo(Clazz clazz, TypeAnnotation typeAnnotation, TypePathInfo typePathInfo) 1062 { 1063 println("kind = " + 1064 typePathInfo.u1typePathKind + ", argument index = " + 1065 typePathInfo.u1typeArgumentIndex); 1066 } 1067 1068 1069 // Implementations for LocalVariableTargetElementVisitor. 1070 1071 public void visitLocalVariableTargetElement(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, LocalVariableTargetInfo localVariableTargetInfo, LocalVariableTargetElement localVariableTargetElement) 1072 { 1073 println("v" + 1074 localVariableTargetElement.u2index + ": " + 1075 localVariableTargetElement.u2startPC + " -> " + 1076 (localVariableTargetElement.u2startPC + localVariableTargetElement.u2length)); 1077 } 1078 1079 1080 // Implementations for ElementValueVisitor. 1081 1082 public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue) 1083 { 1084 println(visitorInfo(constantElementValue) + 1085 " Constant element value [" + 1086 (constantElementValue.u2elementNameIndex == 0 ? "(default)" : 1087 constantElementValue.getMethodName(clazz)) + " '" + 1088 constantElementValue.u1tag + "']"); 1089 1090 indent(); 1091 clazz.constantPoolEntryAccept(constantElementValue.u2constantValueIndex, this); 1092 outdent(); 1093 } 1094 1095 1096 public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue) 1097 { 1098 println(visitorInfo(enumConstantElementValue) + 1099 " Enum constant element value [" + 1100 (enumConstantElementValue.u2elementNameIndex == 0 ? "(default)" : 1101 enumConstantElementValue.getMethodName(clazz)) + ", " + 1102 enumConstantElementValue.getTypeName(clazz) + ", " + 1103 enumConstantElementValue.getConstantName(clazz) + "]"); 1104 } 1105 1106 1107 public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue) 1108 { 1109 println(visitorInfo(classElementValue) + 1110 " Class element value [" + 1111 (classElementValue.u2elementNameIndex == 0 ? "(default)" : 1112 classElementValue.getMethodName(clazz)) + ", " + 1113 classElementValue.getClassName(clazz) + "]"); 1114 } 1115 1116 1117 public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue) 1118 { 1119 println(visitorInfo(annotationElementValue) + 1120 " Annotation element value [" + 1121 (annotationElementValue.u2elementNameIndex == 0 ? "(default)" : 1122 annotationElementValue.getMethodName(clazz)) + "]:"); 1123 1124 indent(); 1125 annotationElementValue.annotationAccept(clazz, this); 1126 outdent(); 1127 } 1128 1129 1130 public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue) 1131 { 1132 println(visitorInfo(arrayElementValue) + 1133 " Array element value [" + 1134 (arrayElementValue.u2elementNameIndex == 0 ? "(default)" : 1135 arrayElementValue.getMethodName(clazz)) + "]:"); 1136 1137 indent(); 1138 arrayElementValue.elementValuesAccept(clazz, annotation, this); 1139 outdent(); 1140 } 1141 1142 1143 // Small utility methods. 1144 1145 private void indent() 1146 { 1147 indentation++; 1148 } 1149 1150 private void outdent() 1151 { 1152 indentation--; 1153 } 1154 1155 private void println(String string) 1156 { 1157 print(string); 1158 println(); 1159 1160 } 1161 1162 private void print(String string) 1163 { 1164 for (int index = 0; index < indentation; index++) 1165 { 1166 ps.print(INDENTATION); 1167 } 1168 1169 ps.print(string); 1170 } 1171 1172 private void println() 1173 { 1174 ps.println(); 1175 } 1176 1177 1178 private String visitorInfo(VisitorAccepter visitorAccepter) 1179 { 1180 return visitorAccepter.getVisitorInfo() == null ? "-" : "+"; 1181 } 1182} 1183