1/* 2 * ProGuard -- shrinking, optimization, obfuscation, and preverification 3 * of Java bytecode. 4 * 5 * Copyright (c) 2002-2009 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.visitor.*; 27import proguard.classfile.attribute.preverification.*; 28import proguard.classfile.attribute.preverification.visitor.*; 29import proguard.classfile.attribute.visitor.*; 30import proguard.classfile.constant.*; 31import proguard.classfile.constant.visitor.ConstantVisitor; 32import proguard.classfile.instruction.*; 33import proguard.classfile.instruction.visitor.InstructionVisitor; 34import proguard.classfile.util.*; 35 36import 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 */ 45public class ClassPrinter 46extends SimplifiedVisitor 47implements 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